Problem/Motivation

CheckoutTest fails locally.

Steps to reproduce

Tests are failing in HEAD with 8.9.x too, as seen in #3168822: PaymentMethodAddForm needs to implement TrustedCallbackInterface for Drupal 9 and several other tasks.
Locally I can see the failures too. When the test passed last time was with 3e85eaa2 (8.x-2.21), but locally tests still fail as looks like Stripe changed their iframe ids.

Proposed resolution

The problem happens when posting in the cart page for navigating to the checkout. It reloads the cart instead of going to the checkout.
Investigate what changed in commerce that broke these tests.

Remaining tasks

TBD

User interface changes

TBD

API changes

TBD

Data model changes

TBD

CommentFileSizeAuthor
#32 3190728-commerce_stripe-fix-checkout-tests-32.patch7.34 KBpenyaskito
#32 3190728-commerce_stripe-fix-checkout-tests.interdiff.30-32.txt863 bytespenyaskito
#29 3190728-commerce_stripe-fix-checkout-tests-30.patch6.74 KBpenyaskito
#29 3190728-commerce_stripe-fix-checkout-tests.interdiff.28-30.txt1.98 KBpenyaskito
#28 3190728-commerce_stripe-fix-checkout-tests-28.patch6.83 KBpenyaskito
#28 3190728-commerce_stripe-fix-checkout-tests.interdiff.26-28.txt899 bytespenyaskito
#26 3190728-commerce_stripe-fix-checkout-tests-26.patch6.48 KBpenyaskito
#26 3190728-commerce_stripe-fix-checkout-tests.interdiff.24-26.txt853 bytespenyaskito
#24 3190728-commerce_stripe-fix-checkout-tests-24.patch6.44 KBpenyaskito
#24 3190728-commerce_stripe-fix-checkout-tests.interdiff.22-24.txt846 bytespenyaskito
#22 interdiff_21-22.txt549 bytesjsacksick
#22 3190728-22.patch6.44 KBjsacksick
#21 3190728-21.patch6.44 KBjsacksick
#17 3190728.head-is-broken-proof.patch409 bytespenyaskito
#16 3190728-commerce_stripe-fix-checkout-tests-16.patch4.22 KBpenyaskito
#16 3190728-commerce_stripe-fix-checkout-tests.interdiff.14-16.txt535 bytespenyaskito
#14 3190728-commerce_stripe-fix-checkout-tests-14.patch4.25 KBpenyaskito
#14 3190728-commerce_stripe-fix-checkout-tests.interdiff.9-14.txt1.81 KBpenyaskito
#9 3190728-commerce_stripe-fix-checkout-tests-9.patch3.48 KBpenyaskito
#9 3190728-commerce_stripe-fix-checkout-tests.interdiff.7-9.txt666 bytespenyaskito
#7 3190728-commerce_stripe-fix-checkout-tests-7.patch3.38 KBpenyaskito
#7 3190728-commerce_stripe-fix-checkout-tests.interdiff.3-7.txt3.14 KBpenyaskito
#3 3190728-commerce_stripe-fix-checkout-tests-2.patch2.34 KBpenyaskito
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

penyaskito created an issue. See original summary.

penyaskito’s picture

Issue summary: View changes

So the first problem is that $this->submitForm([], 'Checkout'); reloads the cart, instead of submitting

penyaskito’s picture

Title: HEAD is broken » Fix CheckoutTest in HEAD
Category: Task » Bug report
Status: Active » Needs review
FileSize
2.34 KB

I couldn't find why $this->submitForm([], 'Checkout'); reloads the form instead of redirecting to checkout. This form is constructed by views, and commerce tests themselves use drupalGet(checkout/1'), so I think it's out of scope of this issue to find out why. Just changing to drupalGet(checkout/1').

For the iframes, looks like Stripe changed the ids. As changing those is not reliable if they change them again, let's get them from the html with xpath.

Status: Needs review » Needs work

The last submitted patch, 3: 3190728-commerce_stripe-fix-checkout-tests-2.patch, failed testing. View results

jonathanshaw’s picture

Nice, I fixed something similar in #3171898: Fix broken HEAD a while ago.

I think the remaining fails may be because you need to do the same fix in the CheckoutTest::complete3Ds() helper.

For the iframes, looks like Stripe changed the ids. As changing those is not reliable if they change them again, let's get them from the html with xpath.

+1

+    $cardIframeId = $this->getSession()->getPage()->find('xpath', '//div[@id="card-number-element"]//iframe')->getAttribute('name');

Maybe it's worth having a switchToElementFrame() helper:

protected function switchToElementFrame($elementId) {
  $elementFrameName = $this->getSession()->getPage()->find('xpath', '//div[@id="$elementId"]//iframe')->getAttribute('name'); 
  $this->switchToFrame($elementFrameName);
}
jonathanshaw’s picture

Priority: Normal » Critical

Broken head is critical for core at least.

penyaskito’s picture

Status: Needs work » Needs review
FileSize
3.14 KB
3.38 KB

I didn't get this to work locally becuase of the nested iframes, but in theory this should work.

jonathanshaw’s picture

Nice.

+++ b/tests/src/FunctionalJavascript/CheckoutTest.php
@@ -583,7 +584,8 @@ class CheckoutTest extends CommerceWebDriverTestBase {
       $stripeFrame = '__privateStripeFrame4';

You missed one :(

penyaskito’s picture

Nice catch, I removed some of my changes before uploading the patch and undid something I shouldn't.
Removed that iframe id, as it's not necessary, it will be the first one in any case.

The last submitted patch, 7: 3190728-commerce_stripe-fix-checkout-tests-7.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 9: 3190728-commerce_stripe-fix-checkout-tests-9.patch, failed testing. View results

jonathanshaw’s picture

Looks like this patch ommitted the changes to CheckoutTest::complete3Ds(). Patches are tricky!

penyaskito’s picture

Looking at this again. The failures are because "challengeFrame" is not found. It's not found because it's generated on-the-fly by the first iframe, which just includes some js, but I still couldn't figure out how is the frame created or anything. Just waiting it's not working. Loading it outside of anything else doesn't help neither.

    $condition = "('complete' === document.readyState)";
    return $this->assertJsCondition($condition, $timeout);

it's not enough, as might be pending js executing or loading.

And we cannot rely on jQuery.active === 0 or alike as there is no jQuery AFAICS in the code by stripe.
There's a window.StripeM object, but cannot know what we are waiting/looking for.

penyaskito’s picture

Status: Needs work » Needs review
FileSize
1.81 KB
4.25 KB

Meh, sometimes you just need to wait in the right moment.

Status: Needs review » Needs work
penyaskito’s picture

Status: Needs work » Needs review
FileSize
535 bytes
4.22 KB

Oops, leftover of my previous tests.

penyaskito’s picture

Proof that the head is broken, as tests only run on commit.

Status: Needs review » Needs work

The last submitted patch, 17: 3190728.head-is-broken-proof.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

penyaskito’s picture

Status: Needs work » Needs review

Tests passed and failed as expected.

jonathanshaw’s picture

Status: Needs review » Reviewed & tested by the community

Nice. These should be more robust to future changes by Stripe.

jsacksick’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
6.44 KB

I made changes to the tests myself locally.

I initially wanted to remove the following changes:

$cart_link = $this->getSession()->getPage()->findLink('your cart');
-    $cart_link->click();
-    $this->submitForm([], 'Checkout');

Since it didn't appear to be related to the original issue, but I realized there was no point in navigating to the cart page. Tests are already really slow, so if we can gain several seconds here and there, I think we should.

I also removed the call to waitForStripe() since we keep retrying until the iframe is found already.

I have a failure locally that I can't really explain, so uploading my patch to see if the issue occurs on drupal.org.

jsacksick’s picture

FileSize
6.44 KB
549 bytes

I think this was due to me removing the sleep(1) in switchToIframe(), tests are now passing for me locally... Probably lost quite some time because of this small change :p.

Status: Needs review » Needs work

The last submitted patch, 22: 3190728-22.patch, failed testing. View results

penyaskito’s picture

This might pass now.

Status: Needs review » Needs work
penyaskito’s picture

Status: Needs work » Needs review
FileSize
853 bytes
6.48 KB

Still timing out without finding the element.

Status: Needs review » Needs work
penyaskito’s picture

This is not waiting enough, probably only running once on the loop.

penyaskito’s picture

Forget about last one. Restored the waitForStripe method. This is the only way we can get this to green.

longwave’s picture

Status: Needs review » Reviewed & tested by the community

The changes look good, and the tests are now green which is the main thing!

Jeff Veit’s picture

Status: Reviewed & tested by the community » Needs work

D8 is passing.
D9 is failing, sadly, because I'd really like this patch committed so that D8 is passing again: it's holding up testing.

penyaskito’s picture

longwave’s picture

Status: Needs review » Reviewed & tested by the community

Thanks for fixing that, this change looks correct to me and the tests are green now.

  • jsacksick committed 55bb50b on 8.x-1.x authored by penyaskito
    Issue #3190728 by penyaskito, jsacksick, jonathanshaw, longwave: Fix...
jsacksick’s picture

Status: Reviewed & tested by the community » Fixed

Committed! Thanks for your contribution penyaskito!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.