Skip to content

Commit 2cab6ee

Browse files
authored
Add SPE e2e tests (#4245)
* Setup tests * Implement utility methods * Add SPE test configuration. * Add tests to cover shortcode and blocks * Include SPE in run-e2e-tests workflow This is currently triggered when manually triggering QIT tests. * Run SPE e2e tests on PRs * Fix PR e2e action to correctly run SPE tests * Refactor setupSPECheckut method - Also fix test when there are multiple payment methods * Fix error when there are multiple payment methods * Fix test name * Fix element visibility check * Fix imports * Make the snackbar selector more specific.
1 parent f6cb1de commit 2cab6ee

File tree

9 files changed

+381
-5
lines changed

9 files changed

+381
-5
lines changed

.github/workflows/e2e-tests.yml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
fail-fast: false
1515
max-parallel: 10
1616
matrix:
17-
checkout: [ 'Default', 'Legacy' ]
17+
checkout: [ 'Default', 'Legacy', 'SPE' ]
1818

1919
name: ${{ matrix.checkout }} WP=latest, WC=latest, PHP=7.4
2020
steps:
@@ -85,7 +85,14 @@ jobs:
8585
env:
8686
STRIPE_PUB_KEY: ${{ secrets.E2E_STRIPE_PUBLISHABLE_KEY }}
8787
STRIPE_SECRET_KEY: ${{ secrets.E2E_STRIPE_SECRET_KEY }}
88-
run: npm run test:e2e${{ matrix.checkout == 'Legacy' && '-legacy' || '' }}
88+
run: |
89+
if [ "${{ matrix.checkout }}" = "Legacy" ]; then
90+
npm run test:e2e-legacy
91+
elif [ "${{ matrix.checkout }}" = "SPE" ]; then
92+
npm run test:e2e-spe
93+
else
94+
npm run test:e2e
95+
fi
8996
9097
- name: Upload ${{ matrix.checkout }} E2E test results
9198
if: ${{ failure() }}
@@ -94,4 +101,4 @@ jobs:
94101
name: ${{ matrix.checkout }}-WP_latest-WC_latest-results
95102
path: tests/e2e/test-results
96103
if-no-files-found: ignore
97-
retention-days: 14
104+
retention-days: 14

.github/workflows/run-e2e-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
fail-fast: false
2121
max-parallel: 10
2222
matrix:
23-
project: [ 'default', 'legacy', 'acss' ]
23+
project: [ 'default', 'legacy', 'acss', 'spe' ]
2424

2525
name: E2E - ${{ matrix.project }} (WP=${{ inputs.wp-version }}, WC=${{ inputs.wc-version }}, PHP=${{ inputs.php-version }})
2626
steps:

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,9 @@
162162
"test:e2e-legacy": "./tests/e2e/bin/run-tests.sh --project=legacy",
163163
"test:e2e-legacy-debug": "npm run test:e2e-legacy -- --debug",
164164
"test:e2e-lpm-acss": "./tests/e2e/bin/run-tests.sh --project=acss",
165-
"test:e2e-lmp-acss-debug": "npm run test:e2e-lpm-acss -- --debug",
165+
"test:e2e-lpm-acss-debug": "npm run test:e2e-lpm-acss -- --debug",
166+
"test:e2e-spe": "./tests/e2e/bin/run-tests.sh --project=spe",
167+
"test:e2e-spe-debug": "npm run test:e2e-spe -- --debug",
166168
"changelog": "node bin/changelog.js"
167169
},
168170
"engines": {

tests/e2e/bin/setup.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ redirect_output cli wp option update _wcstripe_feature_lpm_ach 'yes'
143143
echo " - Enabling the ACSS feature flag"
144144
redirect_output cli wp option update _wcstripe_feature_lpm_acss 'yes'
145145

146+
echo " - Enabling the SPE feature flag"
147+
redirect_output cli wp option update _wcstripe_feature_spe 'yes'
148+
146149
step "Installing Woo Subscriptions"
147150
echo " - Fetching latest version"
148151
LATEST_RELEASE_ASSET_ID=$(curl -sH "Authorization: token $GITHUB_TOKEN" https://api.github.com/repos/woocommerce/woocommerce-subscriptions/releases/latest | jq -r '.assets[0].id')

tests/e2e/config/playwright.config.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,17 @@ const config = {
106106
dependencies: [ 'legacy-setup' ],
107107
use: { ...devices[ 'Desktop Chrome' ] },
108108
},
109+
{
110+
name: 'spe-setup',
111+
testMatch: '/spe.setup.js',
112+
use: { ...devices[ 'Desktop Chrome' ] },
113+
},
114+
{
115+
name: 'spe',
116+
testMatch: '**/spe.spec.js',
117+
dependencies: [ 'spe-setup' ],
118+
use: { ...devices[ 'Desktop Chrome' ] },
119+
},
109120
],
110121
};
111122

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { test, expect } from '@playwright/test';
2+
import { randomUUID } from 'crypto';
3+
import config from 'config';
4+
import { payments, api, user } from '../../../utils';
5+
6+
const {
7+
emptyCart,
8+
setupCart,
9+
setupBlocksCheckout,
10+
setupSPECheckout,
11+
fillSPEDetails,
12+
} = payments;
13+
14+
test.describe( 'SPE payment tests @blocks', () => {
15+
let username, userEmail;
16+
17+
test.describe.configure( { mode: 'serial' } );
18+
19+
test.beforeAll( async ( { browser } ) => {
20+
await test.step( 'Setup test environment', async () => {
21+
// Create test user.
22+
const randomString = randomUUID();
23+
userEmail =
24+
randomString + '+' + config.get( 'users.customer.email' );
25+
username =
26+
randomString + '.' + config.get( 'users.customer.username' );
27+
28+
const testUser = {
29+
...config.get( 'users.customer' ),
30+
...config.get( 'addresses.customer' ),
31+
email: userEmail,
32+
username,
33+
};
34+
await api.create.customer( testUser );
35+
} );
36+
} );
37+
38+
test( 'customer can pay with SPE @smoke', async ( { page } ) => {
39+
await setupSPECheckout( page, 'blocks' );
40+
await fillSPEDetails( page, config.get( 'cards.basic' ) );
41+
await page.locator( 'text=Place order' ).click();
42+
await page.waitForURL( '**/checkout/order-received/**' );
43+
await expect( page.locator( 'h1.entry-title' ) ).toHaveText(
44+
'Order received'
45+
);
46+
} );
47+
48+
test( 'customer can save and reuse SPE payment method @smoke', async ( {
49+
page,
50+
} ) => {
51+
// First order - Save the payment method.
52+
await test.step(
53+
'Save payment method during first checkout',
54+
async () => {
55+
await user.login(
56+
page,
57+
username,
58+
config.get( 'users.customer.password' )
59+
);
60+
await setupSPECheckout( page, 'blocks' );
61+
await page.getByLabel( 'Save payment information' ).click();
62+
// await page.locator( 'text=Place order' ).click();
63+
await fillSPEDetails( page, config.get( 'cards.basic' ) );
64+
await page.locator( 'text=Place order' ).click();
65+
await page.waitForURL( '**/checkout/order-received/**' );
66+
await expect( page.locator( 'h1.entry-title' ) ).toHaveText(
67+
'Order received'
68+
);
69+
}
70+
);
71+
72+
// Second order - Use saved payment method.
73+
await test.step(
74+
'Use saved payment method for second checkout',
75+
async () => {
76+
await emptyCart( page );
77+
await setupCart( page );
78+
await setupBlocksCheckout(
79+
page,
80+
config.get( 'addresses.customer.billing' )
81+
);
82+
await page
83+
.locator( 'label' )
84+
.filter( { hasText: 'Visa ending in 4242 (expires' } )
85+
.click();
86+
await page.locator( 'text=Place order' ).click();
87+
await page.waitForURL( '**/checkout/order-received/**' );
88+
await expect( page.locator( 'h1.entry-title' ) ).toHaveText(
89+
'Order received'
90+
);
91+
}
92+
);
93+
} );
94+
} );
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import { test, expect } from '@playwright/test';
2+
import { randomUUID } from 'crypto';
3+
import config from 'config';
4+
import { payments, api, user } from '../../../utils';
5+
6+
const {
7+
emptyCart,
8+
setupCart,
9+
setupShortcodeCheckout,
10+
setupSPECheckout,
11+
fillSPEDetails,
12+
} = payments;
13+
14+
test.describe( 'SPE payment tests @shortcode', () => {
15+
let username, userEmail;
16+
17+
test.describe.configure( { mode: 'serial' } );
18+
19+
test.beforeAll( async ( { browser } ) => {
20+
await test.step( 'Setup test environment', async () => {
21+
// Create test user.
22+
const randomString = randomUUID();
23+
userEmail =
24+
randomString + '+' + config.get( 'users.customer.email' );
25+
username =
26+
randomString + '.' + config.get( 'users.customer.username' );
27+
28+
const testUser = {
29+
...config.get( 'users.customer' ),
30+
...config.get( 'addresses.customer' ),
31+
email: userEmail,
32+
username,
33+
};
34+
await api.create.customer( testUser );
35+
} );
36+
} );
37+
38+
test( 'customer can pay with SPE @smoke', async ( { page } ) => {
39+
await setupSPECheckout( page, 'shortcode' );
40+
await fillSPEDetails( page, config.get( 'cards.basic' ), 'shortcode' );
41+
await page.locator( 'text=Place order' ).click();
42+
await page.waitForURL( '**/checkout/order-received/**' );
43+
await expect( page.locator( 'h1.entry-title' ) ).toHaveText(
44+
'Order received'
45+
);
46+
} );
47+
48+
test( 'customer can save and reuse SPE payment method @smoke', async ( {
49+
page,
50+
} ) => {
51+
// First order - Save the payment method.
52+
await test.step(
53+
'Save payment method during first checkout',
54+
async () => {
55+
await user.login(
56+
page,
57+
username,
58+
config.get( 'users.customer.password' )
59+
);
60+
await setupSPECheckout( page, 'shortcode' );
61+
await fillSPEDetails(
62+
page,
63+
config.get( 'cards.basic' ),
64+
'shortcode'
65+
);
66+
await page
67+
.getByRole( 'checkbox', {
68+
name: 'Save payment information to',
69+
} )
70+
.click();
71+
await page.locator( 'text=Place order' ).click();
72+
await fillSPEDetails(
73+
page,
74+
config.get( 'cards.basic' ),
75+
'shortcode'
76+
);
77+
await page.waitForURL( '**/checkout/order-received/**' );
78+
await expect( page.locator( 'h1.entry-title' ) ).toHaveText(
79+
'Order received'
80+
);
81+
}
82+
);
83+
84+
// Second order - Use saved payment method.
85+
await test.step(
86+
'Use saved payment method for second checkout',
87+
async () => {
88+
await emptyCart( page );
89+
await setupCart( page );
90+
await setupShortcodeCheckout(
91+
page,
92+
config.get( 'addresses.customer.billing' )
93+
);
94+
await page.getByText( 'Visa ending in 4242 (expires' ).click();
95+
await page.waitForTimeout( 1000 );
96+
await page
97+
.locator( '.woocommerce-SavedPaymentMethods-token' )
98+
.first()
99+
.click();
100+
await page.locator( 'text=Place order' ).click();
101+
await page.waitForURL( '**/checkout/order-received/**' );
102+
await expect( page.locator( 'h1.entry-title' ) ).toHaveText(
103+
'Order received'
104+
);
105+
}
106+
);
107+
} );
108+
} );

tests/e2e/tests/spe.setup.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { test as setup, expect } from '@playwright/test';
2+
3+
setup( 'Configure store for SPE tests', async ( { browser } ) => {
4+
const adminContext = await browser.newContext( {
5+
storageState: process.env.ADMINSTATE,
6+
} );
7+
8+
const page = await adminContext.newPage();
9+
10+
// Enable SPE in the admin.
11+
await page.goto(
12+
'/wp-admin/admin.php?page=wc-settings&tab=checkout&section=stripe&panel=settings'
13+
);
14+
15+
const checkbox = page.getByTestId( 'single-payment-element-checkbox' );
16+
const isChecked = await checkbox.isChecked();
17+
18+
if ( ! isChecked ) {
19+
await checkbox.click();
20+
await page.click( 'text=Save changes' );
21+
await expect(
22+
page.locator(
23+
'.components-snackbar__content:has-text("Settings saved.")'
24+
)
25+
).toBeVisible();
26+
await expect(
27+
page.getByTestId( 'single-payment-element-checkbox' )
28+
).toBeChecked();
29+
}
30+
31+
await adminContext.close();
32+
} );

0 commit comments

Comments
 (0)