Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate the Shopper Renew Subscription E2E test to Playwright #10144

Merged
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: dev

Migrate the Shopper Renew Subscription spec to Playwright and remove the corresponding Puppeteer test.
16 changes: 8 additions & 8 deletions tests/e2e-pw/config/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,25 +76,25 @@ export const config = {
},
'subscriptions-customer': {
billing: {
first_name: 'I am',
last_name: 'Subscriptions Customer',
firstname: 'I am',
lastname: 'Subscriptions Customer',
company: 'Automattic',
country: 'United States (US)',
address_1: '60 29th Street #343',
address_2: 'billing',
addressfirstline: '60 29th Street #343',
addresssecondline: 'billing',
city: 'San Francisco',
state: 'CA',
postcode: '94110',
phone: '123456789',
email: 'e2e-wcpay-subscriptions-customer@woo.com',
},
shipping: {
first_name: 'I am',
last_name: 'Subscriptions Recipient',
firstname: 'I am',
lastname: 'Subscriptions Recipient',
company: 'Automattic',
country: 'United States (US)',
address_1: '60 29th Street #343',
address_2: 'shipping',
addressfirstline: '60 29th Street #343',
addresssecondline: 'shipping',
city: 'San Francisco',
state: 'CA',
postcode: '94110',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* External dependencies
*/
import { test, expect, Page } from '@playwright/test';

/**
* Internal dependencies
*/
import { config } from '../../config/default';
import { describeif, getAnonymousShopper } from '../../utils/helpers';
import * as shopper from '../../utils/shopper';
import * as navigation from '../../utils/shopper-navigation';
import { products, shouldRunSubscriptionsTests } from '../../utils/constants';
import { deleteCustomerByEmailAddress } from '../../utils/rest-api';

describeif( shouldRunSubscriptionsTests )(
'Subscriptions > Renew a subscription in my account',
() => {
const customerBillingConfig =
config.addresses[ 'subscriptions-customer' ].billing;

let subscriptionId: string;
let page: Page;

test.beforeAll( async ( { browser } ) => {
await deleteCustomerByEmailAddress( customerBillingConfig.email );

const { shopperPage } = await getAnonymousShopper( browser );
page = shopperPage;
} );

test( 'should be able to purchase a subscription', async () => {
await shopper.addCartProduct(
page,
products.SUBSCRIPTION_SIGNUP_FEE
);
await shopper.setupCheckout( page, customerBillingConfig );
await shopper.fillCardDetails( page, config.cards.basic );
await shopper.placeOrder( page );
await expect(
page.getByRole( 'heading', { name: 'Order received' } )
).toBeVisible();

subscriptionId = await page
.getByLabel( 'View subscription number' )
.innerText();
} );

test( 'should be able to renew a subscription in my account', async () => {
await navigation.goToSubscriptions( page );

if ( ! subscriptionId ) {
throw new Error( 'Subscription ID is not set' );
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this throw to provide a better error in case the previous test fails. We can remove it if not desired.

}

const numericSubscriptionId = subscriptionId.substring( 1 );

await page
.getByLabel(
`View subscription number ${ numericSubscriptionId }`
)
.click();

await page.getByText( 'Renew now' ).click();
await page
.getByText( 'Complete checkout to renew now.' )
.isVisible();
await page.waitForLoadState( 'networkidle' );

await shopper.placeOrder( page );
await expect(
page.getByRole( 'heading', { name: 'Order received' } )
).toBeVisible();
} );
}
);
6 changes: 6 additions & 0 deletions tests/e2e-pw/utils/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const shouldRunSubscriptionsTests =
process.env.SKIP_WC_SUBSCRIPTIONS_TESTS !== '1';

export const products = {
Copy link
Contributor Author

@eduardoumpierre eduardoumpierre Jan 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unsure about the names of those constants. I wanted to use SHOULD_RUN_SUBSCRIPTIONS_TESTS and PRODUCTS, but since ESLint flagged it, I opted to keep both in lower camel case for now.

SUBSCRIPTION_SIGNUP_FEE: 70,
};
6 changes: 6 additions & 0 deletions tests/e2e-pw/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,9 @@ export const getAnonymousShopper = async (
const shopperPage = await shopperContext.newPage();
return { shopperPage, shopperContext };
};

/**
* Conditionally determine whether or not to skip a test suite.
*/
export const describeif = ( condition: boolean ) =>
condition ? test.describe : test.describe.skip;
52 changes: 52 additions & 0 deletions tests/e2e-pw/utils/rest-api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* External dependencies
*/
import { HTTPClientFactory } from '@woocommerce/api';

/**
* Internal dependencies
*/
import { config } from '../config/default';

const userEndpoint = '/wp/v2/users';

const getAdminClient = () =>
HTTPClientFactory.build( process.env.BASE_URL )
.withBasicAuth(
config.users.admin.username,
config.users.admin.password
)
.create();

Check failure on line 19 in tests/e2e-pw/utils/rest-api.ts

View workflow job for this annotation

GitHub Actions / WC - latest

[shopper] › shopper/shopper-myaccount-renew-subscription.spec.ts:32:7 › Subscriptions > Renew a subscription in my account › should be able to purchase a subscription

1) [shopper] › shopper/shopper-myaccount-renew-subscription.spec.ts:32:7 › Subscriptions > Renew a subscription in my account › should be able to purchase a subscription TypeError: Cannot read properties of undefined (reading 'endsWith') at ../utils/rest-api.ts:19 17 | config.users.admin.password 18 | ) > 19 | .create(); | ^ 20 | 21 | /** 22 | * Deletes a customer account by their email address if the user exists. at HTTPClientFactory.create (/home/runner/work/woocommerce-payments/woocommerce-payments/node_modules/@woocommerce/api/dist/http/http-client-factory.js:71:34) at getAdminClient (/home/runner/work/woocommerce-payments/woocommerce-payments/tests/e2e-pw/utils/rest-api.ts:19:4) at deleteCustomerByEmailAddress (/home/runner/work/woocommerce-payments/woocommerce-payments/tests/e2e-pw/utils/rest-api.ts:30:17) at /home/runner/work/woocommerce-payments/woocommerce-payments/tests/e2e-pw/specs/shopper/shopper-myaccount-renew-subscription.spec.ts:26:38

Check failure on line 19 in tests/e2e-pw/utils/rest-api.ts

View workflow job for this annotation

GitHub Actions / WC - latest

[shopper] › shopper/shopper-myaccount-renew-subscription.spec.ts:32:7 › Subscriptions > Renew a subscription in my account › should be able to purchase a subscription

1) [shopper] › shopper/shopper-myaccount-renew-subscription.spec.ts:32:7 › Subscriptions > Renew a subscription in my account › should be able to purchase a subscription Retry #1 ─────────────────────────────────────────────────────────────────────────────────────── TypeError: Cannot read properties of undefined (reading 'endsWith') at ../utils/rest-api.ts:19 17 | config.users.admin.password 18 | ) > 19 | .create(); | ^ 20 | 21 | /** 22 | * Deletes a customer account by their email address if the user exists. at HTTPClientFactory.create (/home/runner/work/woocommerce-payments/woocommerce-payments/node_modules/@woocommerce/api/dist/http/http-client-factory.js:71:34) at getAdminClient (/home/runner/work/woocommerce-payments/woocommerce-payments/tests/e2e-pw/utils/rest-api.ts:19:4) at deleteCustomerByEmailAddress (/home/runner/work/woocommerce-payments/woocommerce-payments/tests/e2e-pw/utils/rest-api.ts:30:17) at /home/runner/work/woocommerce-payments/woocommerce-payments/tests/e2e-pw/specs/shopper/shopper-myaccount-renew-subscription.spec.ts:26:38

Check failure on line 19 in tests/e2e-pw/utils/rest-api.ts

View workflow job for this annotation

GitHub Actions / WC - latest

[shopper] › shopper/shopper-myaccount-renew-subscription.spec.ts:32:7 › Subscriptions > Renew a subscription in my account › should be able to purchase a subscription

1) [shopper] › shopper/shopper-myaccount-renew-subscription.spec.ts:32:7 › Subscriptions > Renew a subscription in my account › should be able to purchase a subscription Retry #2 ─────────────────────────────────────────────────────────────────────────────────────── TypeError: Cannot read properties of undefined (reading 'endsWith') at ../utils/rest-api.ts:19 17 | config.users.admin.password 18 | ) > 19 | .create(); | ^ 20 | 21 | /** 22 | * Deletes a customer account by their email address if the user exists. at HTTPClientFactory.create (/home/runner/work/woocommerce-payments/woocommerce-payments/node_modules/@woocommerce/api/dist/http/http-client-factory.js:71:34) at getAdminClient (/home/runner/work/woocommerce-payments/woocommerce-payments/tests/e2e-pw/utils/rest-api.ts:19:4) at deleteCustomerByEmailAddress (/home/runner/work/woocommerce-payments/woocommerce-payments/tests/e2e-pw/utils/rest-api.ts:30:17) at /home/runner/work/woocommerce-payments/woocommerce-payments/tests/e2e-pw/specs/shopper/shopper-myaccount-renew-subscription.spec.ts:26:38

/**
* Deletes a customer account by their email address if the user exists.
*
* Copied from https://github.com/woocommerce/woocommerce/blob/trunk/packages/js/e2e-utils/src/flows/with-rest-api.js#L374
*
* @param {string} emailAddress Customer user account email address.
* @return {Promise<void>}
*/
export const deleteCustomerByEmailAddress = async ( emailAddress: string ) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I spent quite some time troubleshooting this issue. I initially tried using the function from WC's test utils, which is used by the Puppeteer tests, but consistently encountered the following error:

Error: Configuration property "url" is not defined

    at Config.get (/woopayments/node_modules/@woocommerce/e2e-utils/node_modules/config/lib/config.js:182:11)
    at Object.<anonymous> (/Users/ronrennick/Sites/solaris/woocommerce/packages/js/e2e-utils/src/factories.js:8:23)
    at Object.<anonymous> (/Users/ronrennick/Sites/solaris/woocommerce/packages/js/e2e-utils/src/index.js:8:1)
    at Object.<anonymous> (/woopayments/tests/e2e-pw/specs/shopper/shopper-myaccount-renew-subscription.spec.ts:6:25)

I attempted to resolve this by adding default.json and test.json with the required keys to the e2e-pw/config folder, following the existing pattern, but it didn’t work. After trying multiple approaches without success, I ended up duplicating the original function and modifying it to work on our setup.

const client = getAdminClient();

const query = {
search: emailAddress,
context: 'edit',
};
const customers = await client.get( userEndpoint, query );

if ( customers.data && customers.data.length ) {
for ( let c = 0; c < customers.data.length; c++ ) {
const deleteUser = {
id: customers.data[ c ].id,
force: true,
reassign: 1,
};

await client.delete(
`${ userEndpoint }/${ deleteUser.id }`,
deleteUser
);
}
}
};
5 changes: 5 additions & 0 deletions tests/e2e-pw/utils/shopper-navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,8 @@ export const goToOrder = async ( page: Page, orderId: string ) => {
waitUntil: 'load',
} );
};

export const goToSubscriptions = ( page: Page ) =>
page.goto( '/my-account/subscriptions/', {
waitUntil: 'load',
} );

This file was deleted.

Loading