2024-02-29 14:32:37 +01:00
|
|
|
import { test, Page, expect } from '@playwright/test';
|
2024-05-22 09:59:58 +02:00
|
|
|
import { waitForRestart } from './restart';
|
|
|
|
import pluralize from 'pluralize';
|
|
|
|
import { kebabCase } from 'lodash/fp';
|
2024-02-06 12:26:06 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Execute a test suite only if the condition is true
|
|
|
|
*/
|
|
|
|
export const describeOnCondition = (shouldDescribe: boolean) =>
|
|
|
|
shouldDescribe ? test.describe : test.describe.skip;
|
2024-02-29 14:32:37 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Navigate to a page and confirm the header, awaiting each step
|
|
|
|
*/
|
|
|
|
export const navToHeader = async (page: Page, navItems: string[], headerText: string) => {
|
|
|
|
for (const navItem of navItems) {
|
|
|
|
// This does not use getByRole because sometimes "Settings" is "Settings 1" if there's a badge notification
|
|
|
|
// BUT if we don't match exact it conflicts with "Advanceed Settings"
|
|
|
|
// As a workaround, we implement our own startsWith with page.locator
|
|
|
|
const item = page.locator(`role=link[name^="${navItem}"]`);
|
|
|
|
await expect(item).toBeVisible();
|
|
|
|
await item.click();
|
|
|
|
}
|
|
|
|
|
|
|
|
const header = page.getByRole('heading', { name: headerText, exact: true });
|
|
|
|
await expect(header).toBeVisible();
|
|
|
|
return header;
|
|
|
|
};
|
2024-03-28 18:55:57 +01:00
|
|
|
|
2024-05-22 09:59:58 +02:00
|
|
|
/**
|
|
|
|
* Skip the tour if the modal is visible
|
|
|
|
*/
|
|
|
|
export const skipCtbTour = async (page: Page) => {
|
|
|
|
const modalSelector = 'role=button[name="Skip the tour"]';
|
|
|
|
|
|
|
|
try {
|
|
|
|
await page.waitForSelector(modalSelector, { timeout: 1000 });
|
|
|
|
const modal = page.locator(modalSelector);
|
|
|
|
if (await modal.isVisible()) {
|
|
|
|
await modal.click();
|
|
|
|
await expect(modal).not.toBeVisible();
|
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
// The modal did not appear, continue with the test
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-03-28 18:55:57 +01:00
|
|
|
/**
|
|
|
|
* Look for an element containing text, and then click a sibling close button
|
|
|
|
*/
|
|
|
|
export const findAndClose = async (
|
|
|
|
page: Page,
|
|
|
|
text: string,
|
|
|
|
role: string = 'status',
|
|
|
|
closeLabel: string = 'Close'
|
|
|
|
) => {
|
|
|
|
// Verify the popup text is visible.
|
2024-06-17 12:50:43 +02:00
|
|
|
const elements = page.locator(`:has-text("${text}")[role="${role}"]`);
|
|
|
|
await expect(elements.first()).toBeVisible(); // expect at least one element
|
2024-03-28 18:55:57 +01:00
|
|
|
|
2024-06-17 12:50:43 +02:00
|
|
|
// Find all 'Close' buttons that are siblings of the elements containing the specified text.
|
|
|
|
const closeBtns = page.locator(
|
2024-04-25 16:17:23 +01:00
|
|
|
`:has-text("${text}")[role="${role}"] ~ button:has-text("${closeLabel}")`
|
2024-03-28 18:55:57 +01:00
|
|
|
);
|
|
|
|
|
2024-06-17 12:50:43 +02:00
|
|
|
// Click all 'Close' buttons.
|
|
|
|
const count = await closeBtns.count();
|
|
|
|
for (let i = 0; i < count; i++) {
|
|
|
|
await closeBtns.nth(i).click();
|
|
|
|
}
|
2024-03-28 18:55:57 +01:00
|
|
|
};
|
2024-05-22 09:59:58 +02:00
|
|
|
|
|
|
|
export const createSingleType = async (page, data) => {
|
|
|
|
const { name, singularId, pluralId } = data;
|
|
|
|
|
|
|
|
await page.getByRole('button', { name: 'Create new single type' }).click();
|
|
|
|
|
|
|
|
await expect(page.getByRole('heading', { name: 'Create a single type' })).toBeVisible();
|
|
|
|
|
|
|
|
const displayName = page.getByLabel('Display name');
|
|
|
|
await displayName.fill(name);
|
|
|
|
|
|
|
|
const singularIdField = page.getByLabel('API ID (Singular)');
|
|
|
|
await expect(singularIdField).toHaveValue(singularId || kebabCase(name));
|
|
|
|
if (singularId) {
|
|
|
|
singularIdField.fill(singularId);
|
|
|
|
}
|
|
|
|
|
|
|
|
const pluralIdField = page.getByLabel('API ID (Plural)');
|
|
|
|
await expect(pluralIdField).toHaveValue(pluralId || pluralize(kebabCase(name)));
|
|
|
|
if (pluralId) {
|
|
|
|
pluralIdField.fill(pluralId);
|
|
|
|
}
|
|
|
|
|
|
|
|
await page.getByRole('button', { name: 'Continue' }).click();
|
|
|
|
|
|
|
|
// Create an initial text field for it
|
|
|
|
await expect(page.getByText('Select a field for your single type')).toBeVisible();
|
|
|
|
await page.getByText('Small or long text').click();
|
|
|
|
await page.getByLabel('Name', { exact: true }).fill('myattribute');
|
|
|
|
await page.getByRole('button', { name: 'Finish' }).click();
|
|
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
|
|
|
|
|
|
await waitForRestart(page);
|
|
|
|
|
|
|
|
await expect(page.getByRole('heading', { name })).toBeVisible();
|
|
|
|
};
|
|
|
|
|
|
|
|
export const createCollectionType = async (page, data) => {
|
|
|
|
const { name, singularId, pluralId } = data;
|
|
|
|
|
|
|
|
await page.getByRole('button', { name: 'Create new collection type' }).click();
|
|
|
|
|
|
|
|
await expect(page.getByRole('heading', { name: 'Create a collection type' })).toBeVisible();
|
|
|
|
|
|
|
|
const displayName = page.getByLabel('Display name');
|
|
|
|
await displayName.fill(name);
|
|
|
|
|
|
|
|
const singularIdField = page.getByLabel('API ID (Singular)');
|
|
|
|
await expect(singularIdField).toHaveValue(singularId || kebabCase(name));
|
|
|
|
if (singularId) {
|
|
|
|
singularIdField.fill(singularId);
|
|
|
|
}
|
|
|
|
|
|
|
|
const pluralIdField = page.getByLabel('API ID (Plural)');
|
|
|
|
await expect(pluralIdField).toHaveValue(pluralId || pluralize(kebabCase(name)));
|
|
|
|
if (pluralId) {
|
|
|
|
pluralIdField.fill(pluralId);
|
|
|
|
}
|
|
|
|
|
|
|
|
await page.getByRole('button', { name: 'Continue' }).click();
|
|
|
|
|
|
|
|
// Create an initial text field for it
|
|
|
|
await expect(page.getByText('Select a field for your collection type')).toBeVisible();
|
|
|
|
await page.getByText('Small or long text').click();
|
|
|
|
await page.getByLabel('Name', { exact: true }).fill('myattribute');
|
|
|
|
await page.getByRole('button', { name: 'Finish' }).click();
|
|
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
|
|
|
|
|
|
await waitForRestart(page);
|
|
|
|
|
|
|
|
await expect(page.getByRole('heading', { name })).toBeVisible();
|
|
|
|
};
|