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

GH-108 New Playwright tests for the versions functionality. #130

Merged
merged 2 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions test/e2e/tests/browse.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import ENV from '../utils/env.js';

test('Get Main Page', async ({ page }) => {
await page.goto(ENV);

const html = await page.content();
expect(html).toContain('Dark Alley');

Expand Down
76 changes: 76 additions & 0 deletions test/e2e/tests/delete.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* 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.
*/
import { test, expect } from '@playwright/test';
import ENV from '../utils/env.js';
import { getTestResourceAge } from '../utils/page.js';

const MIN_HOURS = 2; // Files are deleted after 2 hours

// This test deletes old testing pages that are older than 2 hours
test('Delete multiple old pages', async ({ page }, workerInfo) => {
if (workerInfo.project.name !== 'chromium') {
// only execute this test on chromium
return;
}

test.setTimeout(40000);

// Open the directory listing
await page.goto(`${ENV}/#/da-sites/da-status/tests`);

// Wait for the page to appear
await page.waitForTimeout(1000);

// This page will always be there as its used by a test
await expect(page.getByText('pingtest'), 'Precondition').toBeVisible();

// List the resources and check fot the ones that are to be deleted. These are always pages
// created by the getTestPageURL() function in page.js
const items = page.locator('.da-item-list-item');
let itemsToDelete;
for (let i = 0; i < await items.count(); i += 1) {
const item = items.nth(i);
const fileName = await item.innerText();
console.log('Item', i, fileName, '-', getTestResourceAge(fileName));

// This method checks if the page is a generated test page. If it is, it returns its age in ms.
const age = getTestResourceAge(fileName);
if (!age) {
// eslint-disable-next-line no-continue
continue;
}
const day = 1000 * 60 * 60 * MIN_HOURS;
if (Date.now() - day < age) {
console.log('Too new:', fileName);
// eslint-disable-next-line no-continue
continue;
}

// If we're here the page has to be deleted. We'll tick the checkbox next to it in the page
const checkbox = page.locator('li').filter({ hasText: fileName }).locator('input[type="checkbox"][name="item-selected"]');
console.log('checkboxes:', await checkbox.count());
await checkbox.focus();
await page.keyboard.press(' ');
itemsToDelete = true;
}

if (!itemsToDelete) {
console.log('No items to delete');
return;
}

// Hit the delete button
await page.getByRole('button', { name: 'Delete' }).click();

// Wait for the delete button to disappear which is when we're done
await expect(page.getByRole('button', { name: 'Delete' })).not.toBeVisible({ timeout: 30000 });
});
90 changes: 38 additions & 52 deletions test/e2e/tests/edit.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,74 +11,60 @@
*/
import { test, expect } from '@playwright/test';
import ENV from '../utils/env.js';
import { getTestPageURL } from '../utils/page.js';

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 = `${ENV}/edit#/da-sites/da-status/tests/${pageName}`;
const url = getTestPageURL('edit1', workerInfo);
await page.goto(url);
await expect(page.locator('div.ProseMirror')).toBeVisible();

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);

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();

// 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' });
}
const newPage = await browser.newPage();
await newPage.goto(url);
await expect(newPage.locator('div.ProseMirror')).toBeVisible();
await expect(newPage.locator('div.ProseMirror')).toContainText(enteredText);
});

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}`;
const url = getTestPageURL('edit2', workerInfo);
const pageName = url.split('/').pop();

try {
await page.goto(`${ENV}/#/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.goto(`${ENV}/#/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');
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(`${ENV}/#/da-sites/da-status/tests`);
const newPage = await browser.newPage();
await newPage.goto(`${ENV}/#/da-sites/da-status/tests`);

// Wait 1 sec
await newPage.waitForTimeout(4000);
await newPage.reload();
// 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();
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' });
}
// Wait 1 sec
await page.waitForTimeout(1000);
await expect(newPage.locator(`a[href="/edit#/da-sites/da-status/tests/${pageName}"]`)).not.toBeVisible();
});
41 changes: 16 additions & 25 deletions test/e2e/tests/sheet.spec.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,27 @@
import { test, expect } from '@playwright/test';
import ENV from '../utils/env.js';
import { getTestSheetURL } from '../utils/page.js';

test('New sheet', async ({ page }, workerInfo) => {
test.setTimeout(15000);

const dateStamp = Date.now().toString(36);
const pageName = `pw-test1-${dateStamp}-${workerInfo.project.name}`;
const url = `${ENV}/sheet#/da-sites/da-status/tests/${pageName}`;
const url = getTestSheetURL('sheet1', workerInfo);
await page.goto(url);

try {
await page.goto(url);
// DA title
await expect(page.locator('h1')).toBeVisible();

// DA title
await expect(page.locator('h1')).toBeVisible();
// Sheet tabs
await expect(page.locator('da-sheet-tabs')).toBeVisible();

// Sheet tabs
await expect(page.locator('da-sheet-tabs')).toBeVisible();
// Enter text into first cell
const enteredText = `[${workerInfo.project.name}] Edited by test ${new Date()}`;
await page.locator('[data-x="0"][data-y="0"]').dblclick();
await page.locator('input').fill('key');

// Enter text into first cell
const enteredText = `[${workerInfo.project.name}] Edited by test ${new Date()}`;
await page.locator('[data-x="0"][data-y="0"]').dblclick();
await page.locator('input').fill('key');
// Enter text into second cell
await page.locator('[data-x="0"][data-y="1"]').dblclick();
await page.locator('td input').fill(enteredText);

// Enter text into second cell
await page.locator('[data-x="0"][data-y="1"]').dblclick();
await page.locator('td input').fill(enteredText);

await page.waitForTimeout(3000);
await page.close();
} finally {
// Always delete the document afterwards
// const adminURL = `https://admin.da.live/source/da-sites/da-status/tests/${pageName}.json`;
// await fetch(adminURL, { method: 'DELETE' });
}
await page.waitForTimeout(3000);
await page.close();
});
68 changes: 68 additions & 0 deletions test/e2e/tests/versions.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* 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.
*/
import { test, expect } from '@playwright/test';
import { getTestPageURL } from '../utils/page.js';

test('Create Version and Restore from it', async ({ page }, workerInfo) => {
// This test has a fairly high timeout because it waits for the document to be saved
// a number of times
test.setTimeout(30000);

await page.goto(getTestPageURL('versions', workerInfo));
await expect(page.locator('div.ProseMirror')).toBeVisible();

// Enter some initial text onto the page
await page.locator('div.ProseMirror').fill('Initial version');

// Wait 3 secs to ensure its saved in da-admin
await page.waitForTimeout(3000);

// Create a new stored version called 'ver 1'
await page.getByRole('button', { name: 'Versions' }).click();
await page.locator('button.da-version-btn').click();
await page.locator('input.da-version-new-input').fill('ver 1');
await page.locator('input.da-version-new-input').press('Enter');

// Close the versions panel and add some more text
await page.locator('button.da-versions-close-btn').click();
await page.locator('div.ProseMirror').fill('Some modifications');

// Wait 3 secs to ensure its saved
await page.waitForTimeout(3000);

// And add some more text
await page.locator('div.ProseMirror').fill('Some more modifications');
// Wait 3 secs to ensure its saved
await page.waitForTimeout(3000);

// Reload the page and check that the latest changes are there
await page.reload();
await expect(page.locator('div.ProseMirror'))
.toContainText('Some more modifications');

// Open the versions panel again
await page.getByRole('button', { name: 'Versions' }).click();

// Check that there is an audit entry for the last edit (which we didn't)
// expliticly create a version for.
const audit = await page.locator('.da-version-entry.is-audit');
await audit.click();
await expect(audit).toContainText('anonymous');

// Select 'ver 1' and restore it
await page.getByText('ver 1', { exact: false }).click();
await page.getByRole('button', { name: 'Restore' }).click();
await page.locator('div.da-version-action-area').getByText('Restore').click();

// Ensure that the original text is still there
await expect(page.locator('div.ProseMirror')).toContainText('Initial version');
});
55 changes: 55 additions & 0 deletions test/e2e/utils/page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* 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.
*/
import ENV from './env.js';

function getTestURL(type, testIdentifier, workerInfo) {
const dateStamp = Date.now().toString(36);
const pageName = `pw-${testIdentifier}-${dateStamp}-${workerInfo.project.name}`;
return `${ENV}/${type}#/da-sites/da-status/tests/${pageName}`;
}

/**
* Returns a URL for a single-use test page.
*
* @param {string} testIdentifier - A identifier for the test
* @param {object} workerInfo - workerInfo as passed in by Playwright
* @returns {string} The URL for the test page.
*/
export function getTestPageURL(testIdentifier, workerInfo) {
return getTestURL('edit', testIdentifier, workerInfo);
}

/**
* Returns a URL for a single-use test sheet.
*
* @param {string} testIdentifier - A identifier for the test
* @param {object} workerInfo - workerInfo as passed in by Playwright
* @returns {string} The URL for the test page.
*/
export function getTestSheetURL(testIdentifier, workerInfo) {
return getTestURL('sheet', testIdentifier, workerInfo);
}

/**
* Return the age of the test file by inspecting the timestamp in the filename.
* It also checks if the filename matches the pattern of generated file names.
* @param {String} fileName The file name, as generated in getTestURL()
* @returns The age in ms or null if the file name does not match the pattern.
*/
export function getTestResourceAge(fileName) {
const re = /pw-\w+(-t1)*-(\w+)-\w+/;
const res = re.exec(fileName);
if (res) {
return parseInt(res[2], 36);
}
return null;
}
Loading