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

[#6] - Add tests #41

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,10 @@ vendor/
dist/

.DS_Store
inc/asset-settings.php
inc/asset-settings.php
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
/artifacts
/**/__snapshots__/
3 changes: 3 additions & 0 deletions .wp-env.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"plugins": ["."]
}
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,24 @@ Install PHP packages and create autoloader for the plugin.
composer install
```

### Testing Suite
E2E tests have been created using Playwright.

Run the tests headless.
```
npm run test:e2e
```

Debug the tests in a chromium window.
```
npm run test:e2e:debug
```

Review and run the tests within the Playwright UI.
```
npm run test:e2e -- --ui
```

## Requirements

Image Comparison requires these software with the following versions:
Expand Down
26,967 changes: 20,516 additions & 6,451 deletions package-lock.json

Large diffs are not rendered by default.

13 changes: 10 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
"scripts": {
"build:prod": "build-tools build --production --once",
"build:dev": "build-tools build --once",
"watch:dev": "build-tools build"
"watch:dev": "build-tools build",
"test:e2e": "wp-env start && wp-scripts test-playwright",
"test:e2e:debug": "wp-env start && wp-scripts test-playwright --debug"
},
"dependencies": {
"@wordpress/block-editor": "^13.0.0",
Expand All @@ -18,7 +20,12 @@
"@wordpress/element": "^6.5.0",
"@wordpress/i18n": "^5.0.0"
},
"devDependencies": {
"@bigbite/build-tools": "^1.3.1"
"devDependencies": {
"@axe-core/playwright": "^4.10.1",
"@bigbite/build-tools": "^1.3.1",
"@types/node": "^22.10.0",
"@wordpress/e2e-test-utils-playwright": "^1.12.0",
"@wordpress/env": "^10.12.0",
"@wordpress/scripts": "^30.5.1"
}
}
12 changes: 12 additions & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineConfig } from '@playwright/test';

// Require the wp-scripts Playwright config
const baseConfig = require('@wordpress/scripts/config/playwright.config.js');

const config = defineConfig({
...baseConfig,
// Specific test folder, if required
testDir: './tests/e2e',
globalSetup: './tests/config/global-setup.ts',
});
export default config;
Binary file added tests/assets/after.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/assets/before.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
94 changes: 94 additions & 0 deletions tests/config/block-fixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import type { Page, Locator } from '@playwright/test';

export class BlockFixtures {
constructor(public readonly page: Page) {
//
}

/**
* Adds an image to the first image slot in a block by selecting it from the media library.
*
* @param imageLabel - The aria-label of the image to select from the media library
*
* @usage - await blockFixtures.addImageToAvailableSlot('My Image');
*/
async addImageToAvailableSlot(imageLabel: string) {
await this.page
.locator('iframe[name="editor-canvas"]')
.contentFrame()
.getByRole('button', { name: 'Select Image' })
.first()
.click();

// Get the aria-checked attribute of the image
const isImageSelected = await this.page.getByLabel(imageLabel).getAttribute('aria-checked');

// If the image is not already selected, select it
if (isImageSelected === 'false') {
await this.page.getByLabel(imageLabel).click();
}

// Press the Select button to use the image
await this.page.getByRole('button', { name: 'Select', exact: true }).click();
}

/**
* Adds an image to the second image slot in a block by selecting it from the media library.
*
* @param imageLabel - The aria-label of the image to select from the media library
*
* @usage - await blockFixtures.addImageToSecondSlot('My Image');
*/
async addImageToSecondSlot(imageLabel: string) {
await this.page
.locator('iframe[name="editor-canvas"]')
.contentFrame()
.getByRole('button', { name: 'Select Image' })
.nth(1)
.click();

// Get the aria-checked attribute of the image
const isImageSelected = await this.page.getByLabel(imageLabel).getAttribute('aria-checked');

// If the image is not already selected, select it
if (isImageSelected === 'false') {
await this.page.getByLabel(imageLabel).click();
}

// Press the Select button to use the image
await this.page.getByRole('button', { name: 'Select', exact: true }).click();
}

/**
* Selects the empty caption and populates it with provided text
*
* @param caption - The text to be added as the caption
*
* @usage - await blockFixtures.addCaptionToBlock('Some caption text');
*/
async addCaptionToBlock(caption: string) {
await this.page
.locator('iframe[name="editor-canvas"]')
.contentFrame()
.getByLabel('Please enter a caption')
.click();
await this.page.keyboard.type(caption);
}

/**
* Saves the page and then clicks the snackbar to view the front end
*
* @usage - await blockFixtures.saveVisitPage();
*/
async saveVisitPage() {
// Save the page
await this.page.getByRole('button', { name: 'Publish', exact: true }).click();
await this.page
.getByLabel('Editor publish')
.getByRole('button', { name: 'Publish', exact: true })
.click();

// Visit the page
await this.page.getByTestId('snackbar').getByRole('link', { name: 'View Post' }).click();
}
}
30 changes: 30 additions & 0 deletions tests/config/global-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const { request } = require('@playwright/test');
const { RequestUtils } = require('@wordpress/e2e-test-utils-playwright');

async function globalSetup(config) {
const { storageState, baseURL } = config.projects[0].use;
const storageStatePath = typeof storageState === 'string' ? storageState : undefined;
const requestContext = await request.newContext({
baseURL,
});
const requestUtils = new RequestUtils(requestContext, {
storageStatePath,
});

// Authenticate and save the storageState to disk.
await requestUtils.setupRest();

// Reset the test environment before running the tests.
await Promise.all([
requestUtils.activateTheme('twentytwentyfive'),
requestUtils.deleteAllPosts(),
requestUtils.deleteAllBlocks(),
requestUtils.deleteAllMedia(),
// Prepopulate the media library with before and after images
requestUtils.uploadMedia('./tests/assets/before.png'),
requestUtils.uploadMedia('./tests/assets/after.png'),
requestUtils.resetPreferences(),
]);
await requestContext.dispose();
}
export default globalSetup;
Loading