Try adding performance tests (https://github.com/woocommerce/woocommerce-blocks/pull/6119)
* Add performance script to measure load times of cart and checkout blocks * Temp commit * Temp commit * Temp commit * Remove specific test from performance e2e command * Add performance reporter * Add step to clean performance file before running tests * Add test report constant & average and logPerformanceResult test utils * Update uses of product name constant * Add cart coupon performance test * Check if report file is empty before parsing * Limit performance tests to only ones in performance directory * Round the averages and add a linebreak after each entry in the log * Fix formatting of report and only output after all tests * Log each loading metric as an individual data point * Improve formatting * Get load times in ms from profiler * Revert changes to fixtures * Remove trace.json from git * Remove checkout test file (tests not implemented) * Check performance log file exists before truncating it * Fix checkout coupon test * Remove console logs * Revert to use virtual products after rename of constant * Ignore performance tests when running regular e2e tests * Feedback changes * Tidy up * Fix packag-log.json: Co-authored-by: Alex Florisca <alex.florisca@automattic.com>
This commit is contained in:
parent
d005dbd2cf
commit
10793e8e18
|
@ -67,9 +67,10 @@
|
|||
"storybook:deploy": "rimraf ./storybook/dist/* && npm run storybook:build && gh-pages -d ./storybook/dist",
|
||||
"test": "wp-scripts test-unit-js --config tests/js/jest.config.json",
|
||||
"test:debug": "ndb .",
|
||||
"test:e2e": "npm run wp-env:config && cross-env NODE_CONFIG_DIR=tests/e2e/config wp-scripts test-e2e --config tests/e2e/config/jest.config.js",
|
||||
"test:e2e-dev": "npm run wp-env:config && cross-env NODE_CONFIG_DIR=tests/e2e/config wp-scripts test-e2e --config tests/e2e/config/jest.config.js --puppeteer-interactive",
|
||||
"test:e2e-dev-watch": "npm run wp-env:config && cross-env NODE_CONFIG_DIR=tests/e2e/config wp-scripts test-e2e --config tests/e2e/config/jest.config.js --watch --puppeteer-interactive",
|
||||
"test:e2e": "npm run wp-env:config && cross-env NODE_CONFIG_DIR=tests/e2e/config wp-scripts test-e2e --config tests/e2e/config/jest.config.js --testPathIgnorePatterns performance",
|
||||
"test:performance": "npm run wp-env:config && cross-env NODE_CONFIG_DIR=tests/e2e/config wp-scripts test-e2e --config tests/e2e/config/jest.config.js -- performance",
|
||||
"test:e2e-dev": "npm run wp-env:config && cross-env NODE_CONFIG_DIR=tests/e2e/config wp-scripts test-e2e --config tests/e2e/config/jest.config.js --puppeteer-interactive --testPathIgnorePatterns performance",
|
||||
"test:e2e-dev-watch": "npm run wp-env:config && cross-env NODE_CONFIG_DIR=tests/e2e/config wp-scripts test-e2e --config tests/e2e/config/jest.config.js --watch --puppeteer-interactive --testPathIgnorePatterns performance",
|
||||
"test:e2e:update": "npm run wp-env:config && cross-env NODE_CONFIG_DIR=tests/e2e/config wp-scripts test-e2e --config tests/e2e/config/jest.config.js --updateSnapshot",
|
||||
"test:help": "wp-scripts test-unit-js --help",
|
||||
"pretest:php": "npm run wp-env run composer 'install --no-interaction'",
|
||||
|
@ -132,6 +133,7 @@
|
|||
"@wordpress/dependency-extraction-webpack-plugin": "3.2.1",
|
||||
"@wordpress/dom": "3.2.7",
|
||||
"@wordpress/e2e-test-utils": "6.0.2",
|
||||
"@wordpress/e2e-tests": "^3.1.1",
|
||||
"@wordpress/element": "4.0.4",
|
||||
"@wordpress/env": "4.1.3",
|
||||
"@wordpress/html-entities": "3.2.3",
|
||||
|
|
|
@ -14,6 +14,7 @@ module.exports = {
|
|||
'jest-html-reporters',
|
||||
{ publicPath: './reports/e2e', filename: 'index.html' },
|
||||
],
|
||||
'<rootDir>/tests/e2e/config/performance-reporter.js',
|
||||
],
|
||||
|
||||
testEnvironment: '<rootDir>/tests/e2e/config/environment.js',
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
const { readFileSync, statSync } = require( 'fs' );
|
||||
const chalk = require( 'chalk' );
|
||||
const { PERFORMANCE_REPORT_FILENAME } = require( '../../utils/constants' );
|
||||
|
||||
class PerformanceReporter {
|
||||
onRunComplete() {
|
||||
if ( statSync( PERFORMANCE_REPORT_FILENAME ).size === 0 ) {
|
||||
return;
|
||||
}
|
||||
const reportFileContents = readFileSync( PERFORMANCE_REPORT_FILENAME )
|
||||
.toString()
|
||||
.split( '\n' )
|
||||
.slice( 0, -1 )
|
||||
.map( ( line ) => JSON.parse( line ) );
|
||||
|
||||
reportFileContents.forEach( ( testReport ) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(
|
||||
chalk.black.bgGreen.underline.bold( testReport.description )
|
||||
);
|
||||
// eslint-disable-next-line no-console
|
||||
console.log( chalk.red( `Longest: ${ testReport.longest }ms` ) );
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(
|
||||
chalk.green( `Shortest: ${ testReport.shortest }ms` )
|
||||
);
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(
|
||||
chalk.yellow( `Average: ${ testReport.average.toFixed() }ms` )
|
||||
);
|
||||
// eslint-disable-next-line no-console
|
||||
console.log( '' );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = PerformanceReporter;
|
|
@ -3,6 +3,7 @@
|
|||
* External dependencies
|
||||
*/
|
||||
import { setup as setupPuppeteer } from 'jest-environment-puppeteer';
|
||||
import fs from 'fs';
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
|
@ -20,6 +21,7 @@ import {
|
|||
enablePaymentGateways,
|
||||
createProductAttributes,
|
||||
} from '../fixtures/fixture-loaders';
|
||||
import { PERFORMANCE_REPORT_FILENAME } from '../../utils/constants';
|
||||
|
||||
module.exports = async ( globalConfig ) => {
|
||||
// we need to load puppeteer global setup here.
|
||||
|
@ -64,6 +66,9 @@ module.exports = async ( globalConfig ) => {
|
|||
await createReviews( productId );
|
||||
} );
|
||||
|
||||
// Wipe the performance e2e file at the start of every run
|
||||
fs.truncateSync( PERFORMANCE_REPORT_FILENAME );
|
||||
|
||||
global.fixtureData = {
|
||||
taxes,
|
||||
coupons,
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { shopper, getLoadingDurations } from '../../../utils';
|
||||
import { SIMPLE_PHYSICAL_PRODUCT_NAME } from '../../../utils/constants';
|
||||
import { logPerformanceResult } from '../../utils';
|
||||
|
||||
describe( 'Cart performance', () => {
|
||||
beforeAll( async () => {
|
||||
await shopper.goToShop();
|
||||
await shopper.addToCartFromShopPage( SIMPLE_PHYSICAL_PRODUCT_NAME );
|
||||
} );
|
||||
|
||||
it( 'Loading', async () => {
|
||||
await shopper.block.goToCart();
|
||||
|
||||
const results = {
|
||||
serverResponse: [],
|
||||
firstPaint: [],
|
||||
domContentLoaded: [],
|
||||
loaded: [],
|
||||
firstContentfulPaint: [],
|
||||
firstBlock: [],
|
||||
type: [],
|
||||
focus: [],
|
||||
inserterOpen: [],
|
||||
inserterHover: [],
|
||||
inserterSearch: [],
|
||||
listViewOpen: [],
|
||||
};
|
||||
|
||||
let i = 3;
|
||||
|
||||
// Measuring loading time.
|
||||
while ( i-- ) {
|
||||
await page.reload();
|
||||
await page.waitForSelector( '.wc-block-cart' );
|
||||
const {
|
||||
serverResponse,
|
||||
firstPaint,
|
||||
domContentLoaded,
|
||||
loaded,
|
||||
firstContentfulPaint,
|
||||
firstBlock,
|
||||
} = await getLoadingDurations();
|
||||
|
||||
// Multiply by 1000 to get time in ms
|
||||
results.serverResponse.push( serverResponse * 1000 );
|
||||
results.firstPaint.push( firstPaint * 1000 );
|
||||
results.domContentLoaded.push( domContentLoaded * 1000 );
|
||||
results.loaded.push( loaded * 1000 );
|
||||
results.firstContentfulPaint.push( firstContentfulPaint * 1000 );
|
||||
results.firstBlock.push( firstBlock * 1000 );
|
||||
}
|
||||
|
||||
Object.entries( results ).forEach( ( [ name, value ] ) => {
|
||||
if (
|
||||
Array.isArray( value ) &&
|
||||
value.every( ( x ) => typeof x === 'number' ) &&
|
||||
value.length === 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
logPerformanceResult( `Cart block loading: (${ name })`, value );
|
||||
} );
|
||||
|
||||
// To stop warning about no assertions.
|
||||
expect( true ).toBe( true );
|
||||
} );
|
||||
|
||||
it( 'Quantity change', async () => {
|
||||
await shopper.block.goToCart();
|
||||
await page.waitForSelector(
|
||||
'button.wc-block-components-quantity-selector__button--plus'
|
||||
);
|
||||
let i = 3;
|
||||
|
||||
const timesForResponse = [];
|
||||
while ( i-- ) {
|
||||
const start = performance.now();
|
||||
await expect( page ).toClick(
|
||||
'button.wc-block-components-quantity-selector__button--plus'
|
||||
);
|
||||
await page.waitForResponse(
|
||||
( response ) =>
|
||||
response.url().indexOf( '/wc/store/v1/batch' ) !== -1 &&
|
||||
response.status() === 207
|
||||
);
|
||||
const end = performance.now();
|
||||
timesForResponse.push( end - start );
|
||||
}
|
||||
logPerformanceResult(
|
||||
'Cart block: Change cart item quantity',
|
||||
timesForResponse
|
||||
);
|
||||
} );
|
||||
|
||||
it( 'Coupon entry', async () => {
|
||||
await shopper.block.goToCart();
|
||||
await page.waitForSelector(
|
||||
'button.wc-block-components-quantity-selector__button--plus'
|
||||
);
|
||||
let i = 3;
|
||||
|
||||
const timesForResponse = [];
|
||||
while ( i-- ) {
|
||||
const start = performance.now();
|
||||
await expect( page ).toClick( 'button', { text: 'Coupon code' } );
|
||||
await expect( page ).toFill(
|
||||
'[aria-label="Enter code"]',
|
||||
'test_coupon'
|
||||
);
|
||||
await expect( page ).toClick( 'button', { text: 'Apply' } );
|
||||
await page.waitForResponse(
|
||||
( response ) =>
|
||||
response.url().indexOf( '/wc/store/v1/batch' ) !== -1 &&
|
||||
response.status() === 207
|
||||
);
|
||||
const end = performance.now();
|
||||
// Close the coupon panel.
|
||||
await expect( page ).toClick( 'button', { text: 'Coupon code' } );
|
||||
timesForResponse.push( end - start );
|
||||
}
|
||||
logPerformanceResult( 'Cart block: Coupon entry', timesForResponse );
|
||||
} );
|
||||
} );
|
|
@ -2,7 +2,7 @@
|
|||
* Internal dependencies
|
||||
*/
|
||||
import { shopper } from '../../../utils';
|
||||
import { SIMPLE_PRODUCT_NAME } from '../../../utils/constants';
|
||||
import { SIMPLE_VIRTUAL_PRODUCT_NAME } from '../../../utils/constants';
|
||||
|
||||
const block = {
|
||||
name: 'Cart',
|
||||
|
@ -23,7 +23,7 @@ describe( 'Shopper → Cart → Can proceed to checkout', () => {
|
|||
|
||||
it( 'allows customer to proceed to checkout', async () => {
|
||||
await shopper.goToShop();
|
||||
await shopper.addToCartFromShopPage( SIMPLE_PRODUCT_NAME );
|
||||
await shopper.addToCartFromShopPage( SIMPLE_VIRTUAL_PRODUCT_NAME );
|
||||
await shopper.block.goToCart();
|
||||
|
||||
// Click on "Proceed to Checkout" button
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Internal dependencies
|
||||
*/
|
||||
import { shopper } from '../../../utils';
|
||||
import { SIMPLE_PRODUCT_NAME } from '../../../utils/constants';
|
||||
import { SIMPLE_VIRTUAL_PRODUCT_NAME } from '../../../utils/constants';
|
||||
|
||||
if ( process.env.WOOCOMMERCE_BLOCKS_PHASE < 2 )
|
||||
// eslint-disable-next-line jest/no-focused-tests
|
||||
|
@ -15,7 +15,7 @@ describe( 'Shopper → Cart → Can remove product', () => {
|
|||
|
||||
it( 'Can remove product from cart', async () => {
|
||||
await shopper.goToShop();
|
||||
await shopper.addToCartFromShopPage( SIMPLE_PRODUCT_NAME );
|
||||
await shopper.addToCartFromShopPage( SIMPLE_VIRTUAL_PRODUCT_NAME );
|
||||
await shopper.block.goToCart();
|
||||
const removeProductLink = await page.$(
|
||||
'.wc-block-cart-item__remove-link'
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Internal dependencies
|
||||
*/
|
||||
import { shopper } from '../../../utils';
|
||||
import { SIMPLE_PRODUCT_NAME } from '../../../utils/constants';
|
||||
import { SIMPLE_VIRTUAL_PRODUCT_NAME } from '../../../utils/constants';
|
||||
|
||||
const block = {
|
||||
name: 'Cart',
|
||||
|
@ -23,10 +23,10 @@ describe( 'Shopper → Cart → Can update product quantity', () => {
|
|||
|
||||
it( 'allows customer to update product quantity via the input field', async () => {
|
||||
await shopper.goToShop();
|
||||
await shopper.addToCartFromShopPage( SIMPLE_PRODUCT_NAME );
|
||||
await shopper.addToCartFromShopPage( SIMPLE_VIRTUAL_PRODUCT_NAME );
|
||||
await shopper.block.goToCart();
|
||||
await shopper.block.setCartQuantity( SIMPLE_VIRTUAL_PRODUCT_NAME, 4 );
|
||||
|
||||
await shopper.block.setCartQuantity( SIMPLE_PRODUCT_NAME, 4 );
|
||||
await expect( page ).toMatchElement(
|
||||
'button.wc-block-cart__submit-button[disabled]'
|
||||
);
|
||||
|
@ -35,11 +35,13 @@ describe( 'Shopper → Cart → Can update product quantity', () => {
|
|||
await page.waitForNetworkIdle( { idleTime: 1000 } );
|
||||
await expect( page ).toMatchElement( 'a.wc-block-cart__submit-button' );
|
||||
|
||||
await shopper.block.productIsInCart( SIMPLE_PRODUCT_NAME, 4 );
|
||||
await shopper.block.productIsInCart( SIMPLE_VIRTUAL_PRODUCT_NAME, 4 );
|
||||
} );
|
||||
|
||||
it( 'allows customer to increase product quantity via the plus button', async () => {
|
||||
await shopper.block.increaseCartQuantityByOne( SIMPLE_PRODUCT_NAME );
|
||||
await shopper.block.increaseCartQuantityByOne(
|
||||
SIMPLE_VIRTUAL_PRODUCT_NAME
|
||||
);
|
||||
await expect( page ).toMatchElement(
|
||||
'button.wc-block-cart__submit-button[disabled]'
|
||||
);
|
||||
|
@ -48,11 +50,13 @@ describe( 'Shopper → Cart → Can update product quantity', () => {
|
|||
await page.waitForNetworkIdle( { idleTime: 1000 } );
|
||||
await expect( page ).toMatchElement( 'a.wc-block-cart__submit-button' );
|
||||
|
||||
await shopper.block.productIsInCart( SIMPLE_PRODUCT_NAME, 5 );
|
||||
await shopper.block.productIsInCart( SIMPLE_VIRTUAL_PRODUCT_NAME, 5 );
|
||||
} );
|
||||
|
||||
it( 'allows customer to decrease product quantity via the minus button', async () => {
|
||||
await shopper.block.decreaseCartQuantityByOne( SIMPLE_PRODUCT_NAME );
|
||||
await shopper.block.decreaseCartQuantityByOne(
|
||||
SIMPLE_VIRTUAL_PRODUCT_NAME
|
||||
);
|
||||
await expect( page ).toMatchElement(
|
||||
'button.wc-block-cart__submit-button[disabled]'
|
||||
);
|
||||
|
@ -61,6 +65,6 @@ describe( 'Shopper → Cart → Can update product quantity', () => {
|
|||
await page.waitForNetworkIdle( { idleTime: 1000 } );
|
||||
await expect( page ).toMatchElement( 'a.wc-block-cart__submit-button' );
|
||||
|
||||
await shopper.block.productIsInCart( SIMPLE_PRODUCT_NAME, 4 );
|
||||
await shopper.block.productIsInCart( SIMPLE_VIRTUAL_PRODUCT_NAME, 4 );
|
||||
} );
|
||||
} );
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*/
|
||||
import { shopper } from '../../../utils';
|
||||
|
||||
import { SIMPLE_PRODUCT_NAME } from '../../../utils/constants';
|
||||
import { SIMPLE_VIRTUAL_PRODUCT_NAME } from '../../../utils/constants';
|
||||
|
||||
const PAYMENT_COD = 'Cash on delivery';
|
||||
const PAYMENT_BACS = 'Direct bank transfer';
|
||||
|
@ -24,7 +24,7 @@ describe( 'Shopper → Checkout → Can choose payment option', () => {
|
|||
|
||||
it( 'allows customer to pay using Direct bank transfer', async () => {
|
||||
await shopper.goToShop();
|
||||
await shopper.addToCartFromShopPage( SIMPLE_PRODUCT_NAME );
|
||||
await shopper.addToCartFromShopPage( SIMPLE_VIRTUAL_PRODUCT_NAME );
|
||||
await shopper.block.goToCheckout();
|
||||
await shopper.block.selectPayment( PAYMENT_BACS );
|
||||
await shopper.block.fillInCheckoutWithTestData();
|
||||
|
@ -35,7 +35,7 @@ describe( 'Shopper → Checkout → Can choose payment option', () => {
|
|||
|
||||
it( 'allows customer to pay using Cash on delivery', async () => {
|
||||
await shopper.goToShop();
|
||||
await shopper.addToCartFromShopPage( SIMPLE_PRODUCT_NAME );
|
||||
await shopper.addToCartFromShopPage( SIMPLE_VIRTUAL_PRODUCT_NAME );
|
||||
await shopper.block.goToCheckout();
|
||||
await shopper.block.selectPayment( PAYMENT_COD );
|
||||
await shopper.block.fillInCheckoutWithTestData();
|
||||
|
@ -46,7 +46,7 @@ describe( 'Shopper → Checkout → Can choose payment option', () => {
|
|||
|
||||
it( 'allows customer to pay using Check payments', async () => {
|
||||
await shopper.goToShop();
|
||||
await shopper.addToCartFromShopPage( SIMPLE_PRODUCT_NAME );
|
||||
await shopper.addToCartFromShopPage( SIMPLE_VIRTUAL_PRODUCT_NAME );
|
||||
await shopper.block.goToCheckout();
|
||||
await shopper.block.selectPayment( PAYMENT_CHEQUE );
|
||||
await shopper.block.fillInCheckoutWithTestData();
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
* Internal dependencies
|
||||
*/
|
||||
import { shopper } from '../../../utils';
|
||||
import { SIMPLE_PRODUCT_NAME, BILLING_DETAILS } from '../../../utils/constants';
|
||||
import {
|
||||
SIMPLE_VIRTUAL_PRODUCT_NAME,
|
||||
BILLING_DETAILS,
|
||||
} from '../../../utils/constants';
|
||||
|
||||
if ( process.env.WOOCOMMERCE_BLOCKS_PHASE < 2 )
|
||||
// eslint-disable-next-line jest/no-focused-tests
|
||||
|
@ -12,7 +15,7 @@ describe( 'Shopper → Checkout → Can place an order', () => {
|
|||
it( 'allows customer to place an order as a guest', async () => {
|
||||
await shopper.logout();
|
||||
await shopper.goToShop();
|
||||
await shopper.addToCartFromShopPage( SIMPLE_PRODUCT_NAME );
|
||||
await shopper.addToCartFromShopPage( SIMPLE_VIRTUAL_PRODUCT_NAME );
|
||||
await shopper.block.goToCheckout();
|
||||
await shopper.block.fillBillingDetails( BILLING_DETAILS );
|
||||
await shopper.block.placeOrder();
|
||||
|
@ -22,7 +25,7 @@ describe( 'Shopper → Checkout → Can place an order', () => {
|
|||
it( 'allows customer to place an order as a logged in user', async () => {
|
||||
await shopper.login();
|
||||
await shopper.goToShop();
|
||||
await shopper.addToCartFromShopPage( SIMPLE_PRODUCT_NAME );
|
||||
await shopper.addToCartFromShopPage( SIMPLE_VIRTUAL_PRODUCT_NAME );
|
||||
await shopper.block.goToCheckout();
|
||||
await shopper.block.fillBillingDetails( BILLING_DETAILS );
|
||||
await shopper.block.placeOrder();
|
||||
|
|
|
@ -14,11 +14,13 @@ import {
|
|||
} from '@wordpress/e2e-test-utils';
|
||||
import { addQueryArgs } from '@wordpress/url';
|
||||
import { WP_ADMIN_DASHBOARD } from '@woocommerce/e2e-utils';
|
||||
import fs from 'fs';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { elementExists, getElementData, getTextContent } from './page-utils';
|
||||
import { PERFORMANCE_REPORT_FILENAME } from '../utils/constants';
|
||||
|
||||
/**
|
||||
* @typedef {import('@types/puppeteer').ElementHandle} ElementHandle
|
||||
|
@ -345,7 +347,35 @@ export function useTheme( themeSlug ) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Add a block to Full Site Editing.
|
||||
* Takes an average value of all items in an array.
|
||||
*
|
||||
* @param {Array} array An array of numbers to take an average from.
|
||||
* @return {number} The average value of all members of the array.
|
||||
*/
|
||||
const average = ( array ) => array.reduce( ( a, b ) => a + b ) / array.length;
|
||||
|
||||
/**
|
||||
* Writes a line to the e2e performance result for the current test containing longest, shortest, and average run times.
|
||||
*
|
||||
* @param {string} description Message to describe what you're logging the performance of.
|
||||
* @param {Array} times array of times to record.
|
||||
*/
|
||||
export const logPerformanceResult = ( description, times ) => {
|
||||
const roundedTimes = times.map(
|
||||
( time ) => Math.round( time + Number.EPSILON * 100 ) / 100
|
||||
);
|
||||
fs.appendFileSync(
|
||||
PERFORMANCE_REPORT_FILENAME,
|
||||
JSON.stringify( {
|
||||
description,
|
||||
longest: Math.max( ...roundedTimes ),
|
||||
shortest: Math.min( ...roundedTimes ),
|
||||
average: average( roundedTimes ),
|
||||
} ) + '\n'
|
||||
);
|
||||
};
|
||||
|
||||
/* Add a block to Full Site Editing.
|
||||
*
|
||||
* *Note:* insertBlock function gets focused on the canvas, this could prevent some dialogs from being displayed. e.g. compatibility notice.
|
||||
*
|
||||
|
|
|
@ -8,8 +8,10 @@ const config = require( 'config' );
|
|||
*
|
||||
* @type {string}
|
||||
*/
|
||||
export const SIMPLE_PRODUCT_NAME = 'Woo Single #1';
|
||||
export const SIMPLE_VIRTUAL_PRODUCT_NAME = 'Woo Single #1';
|
||||
export const SIMPLE_PHYSICAL_PRODUCT_NAME = '128GB USB Stick';
|
||||
export const BILLING_DETAILS = config.get( 'addresses.customer.billing' );
|
||||
export const PERFORMANCE_REPORT_FILENAME = 'reports/e2e-performance.json';
|
||||
export const SHIPPING_DETAILS = config.get( 'addresses.customer.shipping' );
|
||||
export const CUSTOMER_USERNAME = config.get( 'users.customer.username' );
|
||||
export const CUSTOMER_PASSWORD = config.get( 'users.customer.password' );
|
||||
|
|
|
@ -9,4 +9,5 @@ export {
|
|||
reactivateCompatibilityNotice,
|
||||
} from './compatibility-notice';
|
||||
export { shopper } from './shopper';
|
||||
export { getLoadingDurations } from './performance';
|
||||
export { selectBlockByName } from './select-block-by-name';
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import type { Page } from 'puppeteer';
|
||||
|
||||
export async function getLoadingDurations(): Promise<
|
||||
ReturnType< Page[ 'evaluate' ] >
|
||||
> {
|
||||
return await page.evaluate( () => {
|
||||
const [
|
||||
{
|
||||
requestStart,
|
||||
responseStart,
|
||||
responseEnd,
|
||||
domContentLoadedEventEnd,
|
||||
loadEventEnd,
|
||||
},
|
||||
] = performance.getEntriesByType(
|
||||
'navigation'
|
||||
) as PerformanceNavigationTiming[];
|
||||
|
||||
const paintTimings = performance.getEntriesByType( 'paint' );
|
||||
return {
|
||||
// Server side metric.
|
||||
serverResponse: responseStart - requestStart,
|
||||
// For client side metrics, consider the end of the response (the
|
||||
// browser receives the HTML) as the start time (0).
|
||||
firstPaint:
|
||||
paintTimings.find( ( { name } ) => name === 'first-paint' )
|
||||
.startTime - responseEnd,
|
||||
domContentLoaded: domContentLoadedEventEnd - responseEnd,
|
||||
loaded: loadEventEnd - responseEnd,
|
||||
firstContentfulPaint:
|
||||
paintTimings.find(
|
||||
( { name } ) => name === 'first-contentful-paint'
|
||||
).startTime - responseEnd,
|
||||
// This is evaluated right after Puppeteer found the block selector.
|
||||
firstBlock: performance.now() - responseEnd,
|
||||
};
|
||||
} );
|
||||
}
|
Loading…
Reference in New Issue