Update Playwright to 1.44.1 from 1.41.1 (#48291)

Co-authored-by: Jon Lane <jon.lane@automattic.com>
Co-authored-by: Bart Kalisz <bartlomiej.kalisz@gmail.com>
Co-authored-by: Adrian Moldovan <3854374+adimoldovan@users.noreply.github.com>
This commit is contained in:
Jonathan Lane 2024-06-11 11:52:48 -07:00 committed by GitHub
parent e64f7b31bc
commit e5e51a41b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 2602 additions and 1251 deletions

View File

@ -94,7 +94,7 @@ jobs:
id: 'setup-monorepo'
with:
install: '${{ matrix.projectName }}...'
build: false
build: '${{ matrix.projectName }}'
- name: 'Lint'
run: 'pnpm --filter="${{ matrix.projectName }}" ${{ matrix.command }}'

View File

@ -136,7 +136,7 @@
"packages": [
"**"
],
"pinVersion": "^1.40.1"
"pinVersion": "^1.44.1"
},
{
"dependencies": [

View File

@ -122,7 +122,7 @@
"@bartekbp/typescript-checkstyle": "5.0.0",
"@octokit/action": "5.0.2",
"@octokit/graphql": "5.0.5",
"@playwright/test": "^1.40.1",
"@playwright/test": "^1.44.1",
"@storybook/addon-a11y": "7.5.2",
"@storybook/addon-actions": "^7.6.4",
"@storybook/addon-docs": "^7.6.4",

View File

@ -40,35 +40,24 @@ export class FrontendUtils {
}
async goToCheckout() {
await this.page.goto( '/checkout', {
waitUntil: 'domcontentloaded',
} );
await this.page.goto( '/checkout' );
await this.page.locator( '#email' ).waitFor();
}
async goToCart() {
await this.page.goto( '/cart', {
waitUntil: 'commit',
} );
await this.page.goto( '/cart' );
}
async goToCartShortcode() {
await this.page.goto( '/cart-shortcode', {
waitUntil: 'commit',
} );
await this.page.goto( '/cart-shortcode' );
}
async goToMiniCart() {
await this.page.goto( '/mini-cart', {
waitUntil: 'domcontentloaded',
} );
await this.page.goto( '/mini-cart' );
}
async goToShop() {
await this.page.goto( '/shop', {
waitUntil: 'commit',
} );
await this.page.goto( '/shop' );
}
async emptyCart() {
@ -101,8 +90,6 @@ export class FrontendUtils {
}
async gotoMyAccount() {
await this.page.goto( '/my-account', {
waitUntil: 'commit',
} );
await this.page.goto( '/my-account' );
}
}

View File

@ -14,9 +14,13 @@ export class MiniCartUtils {
}
async openMiniCart() {
const block = await this.frontendUtils.getBlockByName(
'woocommerce/mini-cart'
const miniCartButton = this.page.locator(
'.wc-block-mini-cart__button'
);
await block.click();
// The mini cart button scripts are loaded when the button is either
// hovered or focused. The click event alone does not trigger neither of
// those actions so we need to perform one explicitly.
await miniCartButton.hover();
await miniCartButton.click();
}
}

View File

@ -0,0 +1,4 @@
Significance: patch
Type: dev
Update Playwright from 1.41.1 to 1.44.1 (latest) and fixed tests

View File

@ -558,7 +558,7 @@
"@babel/core": "7.12.9",
"@babel/preset-env": "7.12.7",
"@babel/register": "7.12.1",
"@playwright/test": "^1.40.1",
"@playwright/test": "^1.44.1",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/experimental-utils": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",

View File

@ -7,12 +7,12 @@ const {
publishPage,
} = require( '../../utils/editor' );
baseTest.describe( 'Transform Classic Cart To Cart Block', () => {
const test = baseTest.extend( {
const test = baseTest.extend( {
storageState: process.env.ADMINSTATE,
testPageTitlePrefix: 'Transformed cart',
} );
} );
test.describe( 'Transform Classic Cart To Cart Block', () => {
test( 'can transform classic cart to cart block', async ( {
page,
testPage,

View File

@ -13,12 +13,12 @@ const singleProductPrice = '999.00';
let productId, shippingZoneId;
baseTest.describe( 'Transform Classic Checkout To Checkout Block', () => {
const test = baseTest.extend( {
const test = baseTest.extend( {
storageState: process.env.ADMINSTATE,
testPageTitlePrefix: 'Transformed checkout',
} );
} );
test.describe( 'Transform Classic Checkout To Checkout Block', () => {
test.beforeAll( async ( { api } ) => {
// enable COD
await api.put( 'payment_gateways/cod', {

View File

@ -1,7 +1,6 @@
const { test: baseTest, expect } = require( '../../fixtures/fixtures' );
baseTest.describe( 'Coupon management', () => {
const couponData = {
const couponData = {
fixedCart: {
code: `fixedCart-${ Date.now() }`,
description: 'Simple fixed cart discount',
@ -29,17 +28,18 @@ baseTest.describe( 'Coupon management', () => {
amount: '1',
freeShipping: true,
},
};
};
const test = baseTest.extend( {
const test = baseTest.extend( {
storageState: process.env.ADMINSTATE,
coupon: async ( { api }, use ) => {
const coupon = {};
await use( coupon );
await api.delete( `coupons/${ coupon.id }`, { force: true } );
},
} );
} );
test.describe( 'Coupon management', () => {
for ( const couponType of Object.keys( couponData ) ) {
test( `can create new ${ couponType } coupon`, async ( {
page,

View File

@ -6,11 +6,11 @@ const {
publishPage,
} = require( '../../utils/editor' );
baseTest.describe( 'Can create a new page', () => {
const test = baseTest.extend( {
const test = baseTest.extend( {
storageState: process.env.ADMINSTATE,
} );
} );
test.describe( 'Can create a new page', () => {
// eslint-disable-next-line playwright/expect-expect
test( 'can create new page', async ( { page, testPage } ) => {
await goToPageEditor( { page } );

View File

@ -6,11 +6,11 @@ const {
publishPage,
} = require( '../../utils/editor' );
baseTest.describe( 'Can create a new post', () => {
const test = baseTest.extend( {
const test = baseTest.extend( {
storageState: process.env.ADMINSTATE,
} );
} );
test.describe( 'Can create a new post', () => {
// eslint-disable-next-line playwright/expect-expect
test( 'can create new post', async ( { page, testPost } ) => {
await goToPostEditor( { page } );

View File

@ -1,7 +1,6 @@
const { test: baseTest, expect } = require( '../../fixtures/fixtures' );
baseTest.describe( 'Restricted coupon management', () => {
const couponData = {
const couponData = {
minimumSpend: {
code: `minSpend-${ new Date().getTime().toString() }`,
description: 'Minimum spend coupon',
@ -33,9 +32,7 @@ baseTest.describe( 'Restricted coupon management', () => {
productCategories: [ 'Uncategorized' ],
},
excludeProductCategories: {
code: `excludeProductCategories-${ new Date()
.getTime()
.toString() }`,
code: `excludeProductCategories-${ new Date().getTime().toString() }`,
description: 'Exclude product categories coupon',
amount: '60',
excludeProductCategories: [ 'Uncategorized' ],
@ -70,9 +67,9 @@ baseTest.describe( 'Restricted coupon management', () => {
amount: '110',
usageLimitPerUser: '2',
},
};
};
const test = baseTest.extend( {
const test = baseTest.extend( {
storageState: process.env.ADMINSTATE,
coupon: async ( { api }, use ) => {
const coupon = {};
@ -97,8 +94,9 @@ baseTest.describe( 'Restricted coupon management', () => {
// Product cleanup
await api.delete( `products/${ product.id }`, { force: true } );
},
} );
} );
test.describe( 'Restricted coupon management', () => {
for ( const couponType of Object.keys( couponData ) ) {
test( `can create new ${ couponType } coupon`, async ( {
page,
@ -379,7 +377,9 @@ baseTest.describe( 'Restricted coupon management', () => {
} )
.click();
await expect(
page.getByRole( 'listitem', { name: 'Uncategorized' } )
page.getByRole( 'listitem', {
name: 'Uncategorized',
} )
).toBeVisible();
} );
}
@ -393,7 +393,9 @@ baseTest.describe( 'Restricted coupon management', () => {
} )
.click();
await expect(
page.getByRole( 'listitem', { name: 'Uncategorized' } )
page.getByRole( 'listitem', {
name: 'Uncategorized',
} )
).toBeVisible();
} );
}

View File

@ -43,12 +43,12 @@ const blocks = [
let productId, shippingZoneId, productTagId, attributeId, productCategoryId;
baseTest.describe( 'Add WooCommerce Blocks Into Page', () => {
const test = baseTest.extend( {
const test = baseTest.extend( {
storageState: process.env.ADMINSTATE,
testPageTitlePrefix: 'Woocommerce Blocks',
} );
} );
test.describe( 'Add WooCommerce Blocks Into Page', () => {
test.beforeAll( async ( { api } ) => {
// add product attribute
await api
@ -159,7 +159,10 @@ baseTest.describe( 'Add WooCommerce Blocks Into Page', () => {
.check();
await canvas
.locator( '.wc-block-reviews-by-product' )
.getByRole( 'button', { name: 'Done', exact: true } )
.getByRole( 'button', {
name: 'Done',
exact: true,
} )
.click();
}

View File

@ -27,12 +27,12 @@ const wooPatterns = [
},
];
baseTest.describe( 'Add WooCommerce Patterns Into Page', () => {
const test = baseTest.extend( {
const test = baseTest.extend( {
storageState: process.env.ADMINSTATE,
testPageTitlePrefix: 'Woocommerce Patterns',
} );
} );
test.describe( 'Add WooCommerce Patterns Into Page', () => {
test( 'can insert WooCommerce patterns into page', async ( {
page,
testPage,

View File

@ -58,8 +58,7 @@ const customerData = {
},
};
baseTest.describe( 'Merchant > Customer List', () => {
const test = baseTest.extend( {
const test = baseTest.extend( {
storageState: process.env.ADMINSTATE,
customers: async ( { api }, use ) => {
const customers = [];
@ -76,8 +75,9 @@ baseTest.describe( 'Merchant > Customer List', () => {
delete: customers.map( ( customer ) => customer.id ),
} );
},
} );
} );
test.describe( 'Merchant > Customer List', () => {
test.beforeEach( async ( { context } ) => {
// prevents the column picker from saving state between tests
await context.route( '**/users/**', ( route ) => route.abort() );

View File

@ -1,7 +1,6 @@
const { test: baseTest, expect } = require( '../../fixtures/fixtures' );
baseTest.describe( 'Products > Delete Product', () => {
const test = baseTest.extend( {
const test = baseTest.extend( {
storageState: process.env.ADMINSTATE,
product: async ( { api }, use ) => {
let product = {
@ -33,8 +32,9 @@ baseTest.describe( 'Products > Delete Product', () => {
await use( page );
},
} );
} );
test.describe( 'Products > Delete Product', () => {
test( 'can delete a product from edit view', async ( {
page,
product,

View File

@ -11,8 +11,7 @@ async function addImageFromLibrary( page, imageName, actionButtonName ) {
return dataId;
}
baseTest.describe( 'Products > Product Images', () => {
const test = baseTest.extend( {
const test = baseTest.extend( {
storageState: process.env.ADMINSTATE,
product: async ( { api }, use ) => {
let product = {
@ -70,8 +69,9 @@ baseTest.describe( 'Products > Product Images', () => {
await use( productWithGallery );
},
} );
} );
test.describe( 'Products > Product Images', () => {
test( 'can set product image', async ( { page, product } ) => {
await test.step( 'Navigate to product edit page', async () => {
await page.goto(
@ -192,7 +192,9 @@ baseTest.describe( 'Products > Product Images', () => {
for ( const image of images ) {
await page
.getByRole( 'link', { name: 'Add product gallery images' } )
.getByRole( 'link', {
name: 'Add product gallery images',
} )
.click();
const dataId = await addImageFromLibrary(
page,

View File

@ -1,7 +1,6 @@
const { test: baseTest, expect } = require( '../../fixtures/fixtures' );
baseTest.describe( 'Products > Related products', () => {
const test = baseTest.extend( {
const test = baseTest.extend( {
storageState: process.env.ADMINSTATE,
products: async ( { api }, use ) => {
const keys = [ 'main', 'linked1', 'linked2' ];
@ -26,8 +25,9 @@ baseTest.describe( 'Products > Related products', () => {
await api.delete( `products/${ product.id }`, { force: true } );
}
},
} );
} );
test.describe( 'Products > Related products', () => {
async function navigate( page, productId ) {
await test.step( 'Navigate to product edit page', async () => {
await page.goto(
@ -44,7 +44,10 @@ baseTest.describe( 'Products > Related products', () => {
await test.step( 'update the product', async () => {
// extra click somewhere in the page as a workaround for update button click not always working
await page
.getByRole( 'heading', { name: 'Edit product', exact: true } )
.getByRole( 'heading', {
name: 'Edit product',
exact: true,
} )
.click();
await page.getByRole( 'button', { name: 'Update' } ).click();
await expect( page.getByText( 'Product updated.' ) ).toBeVisible();
@ -140,7 +143,9 @@ baseTest.describe( 'Products > Related products', () => {
await page.keyboard.press( 'Backspace' );
await expect(
page.getByRole( 'listitem', { name: products.linked1.name } )
page.getByRole( 'listitem', {
name: products.linked1.name,
} )
).toBeHidden();
} );
@ -247,7 +252,9 @@ baseTest.describe( 'Products > Related products', () => {
await page.keyboard.press( 'Backspace' );
await expect(
page.getByRole( 'listitem', { name: products.linked1.name } )
page.getByRole( 'listitem', {
name: products.linked1.name,
} )
).toBeHidden();
} );

View File

@ -1,7 +1,6 @@
const { test: baseTest, expect } = require( '../../fixtures/fixtures' );
baseTest.describe( 'Product Reviews > Edit Product Review', () => {
const test = baseTest.extend( {
const test = baseTest.extend( {
storageState: process.env.ADMINSTATE,
reviews: async ( { api }, use ) => {
const timestamp = Date.now().toString();
@ -46,8 +45,9 @@ baseTest.describe( 'Product Reviews > Edit Product Review', () => {
delete: products.map( ( product ) => product.id ),
} );
},
} );
} );
test.describe( 'Product Reviews > Edit Product Review', () => {
test( 'can view products reviews list', async ( { page, reviews } ) => {
await page.goto(
`wp-admin/edit.php?post_type=product&page=product-reviews`

View File

@ -479,13 +479,11 @@ test.describe( 'Update variations', () => {
await test.step( 'Expect the default attributes to be pre-selected', async () => {
for ( const attribute of defaultVariation ) {
await test.step( `Expect "${ attribute.option }" is selected as the default "${ attribute.name }"`, async () => {
const defaultSelectedAttribute = page
.getByRole( 'row', {
name: attribute.name,
} )
.locator( 'option[selected]' );
const defaultSelectedAttribute = page.getByLabel(
attribute.name
);
await expect( defaultSelectedAttribute ).toHaveText(
await expect( defaultSelectedAttribute ).toContainText(
attribute.option
);
} );

View File

@ -18,8 +18,7 @@ const shippingCountryNL = 'NL';
const shippingZoneNamePT = 'Portugal Flat Local';
const shippingCountryPT = 'PT';
baseTest.describe( 'Cart Block Calculate Shipping', () => {
const test = baseTest.extend( {
const test = baseTest.extend( {
storageState: process.env.ADMINSTATE,
testPageTitlePrefix: 'Cart Block',
cartBlockPage: async ( { page, testPage }, use ) => {
@ -30,8 +29,9 @@ baseTest.describe( 'Cart Block Calculate Shipping', () => {
await use( testPage );
},
} );
} );
test.describe( 'Cart Block Calculate Shipping', () => {
let product1Id, product2Id, shippingZoneNLId, shippingZonePTId;
test.beforeAll( async ( { api } ) => {

View File

@ -34,8 +34,7 @@ const customerBilling = {
let productId, orderId, limitedCouponId;
baseTest.describe( 'Cart Block Applying Coupons', () => {
const test = baseTest.extend( {
const test = baseTest.extend( {
storageState: process.env.ADMINSTATE,
testPageTitlePrefix: 'Cart Block',
page: async ( { context, page, testPage }, use ) => {
@ -54,8 +53,9 @@ baseTest.describe( 'Cart Block Applying Coupons', () => {
await use( page );
},
} );
} );
test.describe( 'Cart Block Applying Coupons', () => {
const couponBatchId = [];
test.beforeAll( async ( { api } ) => {

View File

@ -21,12 +21,12 @@ const singleProductWithCrossSellProducts =
let product1Id, product2Id, product3Id;
baseTest.describe( 'Cart Block page', () => {
const test = baseTest.extend( {
const test = baseTest.extend( {
storageState: process.env.ADMINSTATE,
testPageTitlePrefix: 'Cart Block',
} );
} );
test.describe( 'Cart Block page', () => {
test.beforeAll( async ( { api } ) => {
// make sure the currency is USD
await api.put( 'settings/general/woocommerce_currency', {

View File

@ -35,8 +35,7 @@ const customerBilling = {
let productId, orderId, limitedCouponId;
baseTest.describe( 'Checkout Block Applying Coupons', () => {
const test = baseTest.extend( {
const test = baseTest.extend( {
storageState: process.env.ADMINSTATE,
testPageTitlePrefix: 'Checkout Block',
page: async ( { context, page, testPage }, use ) => {
@ -55,8 +54,9 @@ baseTest.describe( 'Checkout Block Applying Coupons', () => {
await use( page );
},
} );
} );
test.describe( 'Checkout Block Applying Coupons', () => {
const couponBatchId = [];
test.beforeAll( async ( { api } ) => {

View File

@ -34,8 +34,7 @@ let guestOrderId1,
productId,
shippingZoneId;
baseTest.describe( 'Checkout Block page', () => {
const test = baseTest.extend( {
const test = baseTest.extend( {
storageState: process.env.ADMINSTATE,
testPageTitlePrefix: 'Checkout Block',
page: async ( { context, page, testPage }, use ) => {
@ -48,8 +47,9 @@ baseTest.describe( 'Checkout Block page', () => {
await use( page );
},
} );
} );
test.describe( 'Checkout Block page', () => {
test.beforeAll( async ( { baseURL } ) => {
const api = new wcApi( {
url: baseURL,
@ -139,7 +139,9 @@ baseTest.describe( 'Checkout Block page', () => {
`Customer with email ${ newAccountEmail } exists! Deleting it before starting test...`
);
await api.delete( `customers/${ customerId }`, { force: true } );
await api.delete( `customers/${ customerId }`, {
force: true,
} );
}
// make sure our customer user has a pre-defined billing/shipping address
await api.put( `customers/2`, {
@ -201,13 +203,19 @@ baseTest.describe( 'Checkout Block page', () => {
);
// delete the orders we created
if ( guestOrderId1 ) {
await api.delete( `orders/${ guestOrderId1 }`, { force: true } );
await api.delete( `orders/${ guestOrderId1 }`, {
force: true,
} );
}
if ( guestOrderId2 ) {
await api.delete( `orders/${ guestOrderId2 }`, { force: true } );
await api.delete( `orders/${ guestOrderId2 }`, {
force: true,
} );
}
if ( customerOrderId ) {
await api.delete( `orders/${ customerOrderId }`, { force: true } );
await api.delete( `orders/${ customerOrderId }`, {
force: true,
} );
}
if ( newAccountOrderId ) {
await api.delete( `orders/${ newAccountOrderId }`, {

View File

@ -15,12 +15,13 @@ const simpleProductName = 'AAA Filter Products';
let product1Id, product2Id, product3Id;
baseTest.describe( 'Filter items in the shop by product price', () => {
const test = baseTest.extend( {
// Extend the baseTest object
const test = baseTest.extend( {
storageState: process.env.ADMINSTATE,
testPageTitlePrefix: 'Products filter',
} );
} );
test.describe( 'Filter items in the shop by product price', () => {
test.beforeAll( async ( { api } ) => {
// add products
await api

View File

@ -136,7 +136,11 @@ test.describe( 'Search, browse by categories and sort items in the shop', () =>
await page.goto( 'shop/' );
// sort by price high to low
await page.locator( '.orderby' ).selectOption( 'price-desc' );
await page.getByLabel( 'Shop order' ).selectOption( 'price-desc' );
await expect(
page.getByText( 'Add to cart View cart' ).nth( 2 )
).toBeVisible();
// Check that the priciest appears before the cheapest in the list
const highToLowList = await page
@ -154,7 +158,11 @@ test.describe( 'Search, browse by categories and sort items in the shop', () =>
);
// sort by price low to high
await page.locator( '.orderby' ).selectOption( 'price' );
await page.getByLabel( 'Shop order' ).selectOption( 'price' );
await expect(
page.getByText( 'Add to cart View cart' ).nth( 2 )
).toBeVisible();
// Check that the cheapest appears before the priciest in the list
const lowToHighList = await page

View File

@ -1,109 +0,0 @@
const {
ADMINSTATE,
GITHUB_TOKEN,
PLUGIN_NAME,
PLUGIN_REPOSITORY,
PLUGIN_SLUG,
} = process.env;
const { test, expect } = require( '@playwright/test' );
const { admin } = require( '../../test-data/data' );
const {
deletePlugin,
deleteZip,
downloadZip,
installPluginThruWpCli,
} = require( '../../utils/plugin-utils' );
const skipMessage = 'Skipping this test because PLUGIN_REPOSITORY is undefined';
const deletePluginFromSite = async ( { request, baseURL } ) => {
await deletePlugin( {
request,
baseURL,
slug: PLUGIN_SLUG,
username: admin.username,
password: admin.password,
} );
};
let pluginPath;
test.skip( () => {
const shouldSkip = ! PLUGIN_REPOSITORY;
if ( shouldSkip ) {
console.log( skipMessage );
}
return shouldSkip;
}, skipMessage );
test.describe( `${ PLUGIN_NAME } plugin can be uploaded and activated`, () => {
test.use( { storageState: ADMINSTATE } );
test.beforeAll( async ( { playwright, baseURL } ) => {
pluginPath =
await test.step( `Download ${ PLUGIN_NAME } plugin zip`, async () => {
return downloadZip( {
repository: PLUGIN_REPOSITORY,
authorizationToken: GITHUB_TOKEN,
} );
} );
await test.step( "Delete plugin from test site if it's installed.", async () => {
await deletePluginFromSite( {
request: playwright.request,
baseURL,
} );
} );
} );
test.afterAll( async ( { playwright, baseURL } ) => {
await test.step( "Delete plugin from test site if it's installed.", async () => {
await deletePluginFromSite( {
request: playwright.request,
baseURL,
} );
} );
await test.step( 'Delete the downloaded zip', async () => {
await deleteZip( pluginPath );
} );
} );
test( `can upload and activate "${ PLUGIN_NAME }"`, async ( { page } ) => {
await test.step( `Install "${ PLUGIN_NAME }" through WP CLI`, async () => {
await installPluginThruWpCli( pluginPath );
} );
await test.step( 'Go to the "Installed Plugins" page', async () => {
await page.goto( 'wp-admin/plugins.php' );
} );
await test.step( `Expect "${ PLUGIN_NAME }" to be listed and active.`, async () => {
await expect(
page.getByLabel( `Deactivate ${ PLUGIN_NAME }` )
).toBeVisible();
} );
await test.step( 'Expect the shop to load successfully.', async () => {
const shopHeading = page.getByRole( 'heading', {
name: 'Shop',
} );
await page.goto( '/shop' );
await expect( shopHeading ).toBeVisible();
} );
await test.step( 'Expect the WooCommerce Homepage to load successfully.', async () => {
const statsOverviewHeading = page.getByText( 'Stats overview' );
const skipSetupStoreLink = page.getByRole( 'button', {
name: 'Set up my store',
} );
await page.goto( '/wp-admin/admin.php?page=wc-admin' );
await expect(
statsOverviewHeading.or( skipSetupStoreLink )
).toBeVisible();
} );
} );
} );

File diff suppressed because it is too large Load Diff