Skip to content

Commit

Permalink
GH-84 - Some initial e2e tests (#85)
Browse files Browse the repository at this point in the history
* Initial playwright tests
* With github action that runs on PRs

---------

Co-authored-by: Chris Millar <[email protected]>
  • Loading branch information
bosschaert and auniverseaway authored Apr 5, 2024
1 parent 3a014fc commit 6e0a436
Show file tree
Hide file tree
Showing 13 changed files with 323 additions and 7 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
deps
test/e2e/playwright.config.js
28 changes: 28 additions & 0 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Playwright Tests
on:
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened]
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install dependencies
run: cd test/e2e && npm ci
- name: Install Playwright Browsers
run: cd test/e2e && npx playwright install --with-deps
- name: Run Playwright tests
run: cd test/e2e && npm run test:all
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: test/e2e/playwright-report/
retention-days: 30
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@
"lint:css": "stylelint blocks/**/*.css styles/*.css",
"lint": "npm run lint:js && npm run lint:css",
"copy:deps": "node ./deps/copy.js",
"test": "wtr \"./test/**/*.test.js\" --node-resolve --port=2000 --coverage",
"test": "wtr \"./test/unit/**/*.test.js\" --node-resolve --port=2000 --coverage",
"test:watch": "npm test -- --watch",
"test:e2e": "cd test/e2e && npm i && npm run test:all",
"build:da-y-wrapper": "esbuild --format=esm --minify ./deps/da-y-wrapper/src/index.js --bundle --outfile=./deps/da-y-wrapper/dist/index.js"
}
}
5 changes: 5 additions & 0 deletions test/e2e/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules/
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
90 changes: 90 additions & 0 deletions test/e2e/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions test/e2e/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "da-live_e2e_test",
"version": "1.0.0",
"scripts": {
"test": "playwright test --project=chromium",
"test:all": "playwright test --project=chromium --project=firefox # limit to Chromium and FF as webkit currently fails",
"test:ui": "playwright test --project=chromium --ui",
"test:debug": "playwright test --project=chromium --debug"
},
"keywords": ["test"],
"devDependencies": {
"@playwright/test": "^1.42.1",
"@types/node": "^20.11.27"
}
}
79 changes: 79 additions & 0 deletions test/e2e/playwright.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// @ts-check
const { defineConfig, devices } = require('@playwright/test');

/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config();

/**
* @see https://playwright.dev/docs/test-configuration
*/
module.exports = defineConfig({
testDir: './tests',
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
// baseURL: 'http://127.0.0.1:3000',

/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',
},

/* Configure projects for major browsers */
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},

{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},

{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},

/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: { ...devices['Pixel 5'] },
// },
// {
// name: 'Mobile Safari',
// use: { ...devices['iPhone 12'] },
// },

/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
// },
// {
// name: 'Google Chrome',
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
// },
],

/* Run your local dev server before starting the tests */
// webServer: {
// command: 'npm run start',
// url: 'http://127.0.0.1:3000',
// reuseExistingServer: !process.env.CI,
// },
});

97 changes: 97 additions & 0 deletions test/e2e/tests/edit.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Copyright 2024 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
/* eslint-disable import/no-unresolved */
const { test, expect } = require('@playwright/test');

const DA_BRANCH = process.env.GITHUB_HEAD_REF || 'main';
const DA_HOST = `https://${DA_BRANCH}--da-live--adobe.hlx.live`;
console.log('Using DA_URL', DA_HOST);

test('Get Main Page', async ({ page }) => {
await page.goto(DA_HOST);
const html = await page.content();
expect(html).toContain('Dark Alley');

await expect(page.locator('a.nx-nav-brand')).toBeVisible();
await expect(page.locator('a.nx-nav-brand')).toContainText('Project Dark Alley');
});

test('Update Document', async ({ browser, page }, workerInfo) => {
test.setTimeout(15000);

const dateStamp = Date.now().toString(36);
const pageName = `pw-test1-${dateStamp}-${workerInfo.project.name}`;
const url = `${DA_HOST}/edit#/da-sites/da-status/tests/${pageName}`;

try {
await page.goto(url);
await expect(page.locator('div.ProseMirror')).toBeVisible();

const enteredText = `[${workerInfo.project.name}] Edited by test ${new Date()}`;
await page.locator('div.ProseMirror').fill(enteredText);

// Wait 3 secs
await page.waitForTimeout(3000);
await page.close();

const newPage = await browser.newPage();
await newPage.goto(url);
await expect(newPage.locator('div.ProseMirror')).toBeVisible();
await expect(newPage.locator('div.ProseMirror')).toContainText(enteredText);
} finally {
// Always delete the document afterwards
const adminURL = `https://admin.da.live/source/da-sites/da-status/tests/${pageName}.html`;
await fetch(adminURL, { method: 'DELETE' });
}
});

test('Create Delete Document', async ({ browser, page }, workerInfo) => {
test.setTimeout(15000);

const dateStamp = Date.now().toString(36);
const pageName = `pw-test2-${dateStamp}-${workerInfo.project.name}`;

try {
await page.goto(`${DA_HOST}/#/da-sites/da-status/tests`);
await page.locator('button.da-actions-new-button').click();
await page.locator('button:text("Document")').click();
await page.locator('input.da-actions-input').fill(pageName);

await page.locator('button:text("Create document")').click();
await expect(page.locator('div.ProseMirror')).toBeVisible();
await page.locator('div.ProseMirror').fill('testcontent');

const newPage = await browser.newPage();
await newPage.goto(`${DA_HOST}/#/da-sites/da-status/tests`);

// Wait 1 sec
await newPage.waitForTimeout(4000);
await newPage.reload();

await expect(newPage.locator(`a[href="/edit#/da-sites/da-status/tests/${pageName}"]`)).toBeVisible();
await newPage.locator(`a[href="/edit#/da-sites/da-status/tests/${pageName}"]`).focus();
// Note this currently does not work on webkit as the checkbox isn't keyboard focusable there
await newPage.keyboard.press('Shift+Tab');
await newPage.keyboard.press(' ');
await newPage.waitForTimeout(500);
await expect(newPage.locator('button.delete-button')).toBeVisible();
await newPage.locator('button.delete-button').click();

// Wait 1 sec
await page.waitForTimeout(1000);
await expect(newPage.locator(`a[href="/edit#/da-sites/da-status/tests/${pageName}"]`)).not.toBeVisible();
} finally {
// Delete the document even if the test fails;
const adminURL = `https://admin.da.live/source/da-sites/da-status/tests/${pageName}.html`;
await fetch(adminURL, { method: 'DELETE' });
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { expect } from '@esm-bundle/chai';

// This is needed to make a dynamic import work that is indirectly referenced
// from edit/prose/index.js
const { setNx } = await import('../../../scripts/utils.js');
const { setNx } = await import('../../../../scripts/utils.js');
setNx('/bheuaark/', { hostname: 'localhost' });

const pi = await import('../../../blocks/edit/prose/index.js');
const pi = await import('../../../../blocks/edit/prose/index.js');

describe('Prose collab', () => {
it('Test awareness status', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect } from '@esm-bundle/chai';
import { getDaAdmin, COLLAB_ORIGIN } from '../../../blocks/shared/constants.js';
import { getDaAdmin, COLLAB_ORIGIN } from '../../../../blocks/shared/constants.js';

import '../../milo.js';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { expect } from '@esm-bundle/chai';
import '../../milo.js';

// Dynamic import because Milo dependency
const { default: getPathDetails } = await import('../../../blocks/shared/pathDetails.js');
const { default: getPathDetails } = await import('../../../../blocks/shared/pathDetails.js');

describe('Path details', () => {
describe('Org only', () => {
Expand Down
2 changes: 1 addition & 1 deletion test/milo.js → test/unit/milo.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { setNx, codeBase } from '../scripts/utils.js';
import { setNx, codeBase } from '../../scripts/utils.js';

const nx = setNx('https://da.live/nx');
const { setConfig } = await import(`${nx}/scripts/nexter.js`);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect } from '@esm-bundle/chai';
import { setNx } from '../../scripts/utils.js';
import { setNx } from '../../../scripts/utils.js';

describe('Libs', () => {
it('Default Libs', () => {
Expand Down

0 comments on commit 6e0a436

Please sign in to comment.