201 lines
7.6 KiB
JavaScript
201 lines
7.6 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import process from 'node:process';
|
|
const { chromium } = await import(
|
|
process.env.PLAYWRIGHT_MODULE ?? 'playwright'
|
|
);
|
|
const browser = await chromium.launch({ channel: 'chrome', headless: true });
|
|
const context = await browser.newContext({ reducedMotion: 'reduce' });
|
|
const page = await context.newPage();
|
|
page.setDefaultTimeout(10000);
|
|
const errors = [];
|
|
page.on('pageerror', (error) => errors.push(error.message));
|
|
const base = 'http://127.0.0.1:4197';
|
|
const result = (value) =>
|
|
context.addCookies([{ name: 'teams_result', value, url: base }]);
|
|
const visit = async (query = '') => {
|
|
await result('success');
|
|
await page.goto(base + '/teams?reset' + query);
|
|
await page.getByRole('heading', { name: 'Teams', exact: true }).waitFor();
|
|
};
|
|
const button = (name) => page.getByRole('button', { name, exact: true });
|
|
const dialog = () => page.getByRole('dialog');
|
|
const state = (value) =>
|
|
dialog()
|
|
.locator('[data-form-state="' + value + '"]')
|
|
.waitFor({ state: 'visible' });
|
|
const noOverflow = async () =>
|
|
assert.equal(
|
|
await page.evaluate(
|
|
() => document.documentElement.scrollWidth <= innerWidth,
|
|
),
|
|
true,
|
|
);
|
|
const save = async (label) => {
|
|
const request = page.waitForRequest((r) =>
|
|
['POST', 'PATCH'].includes(r.method()),
|
|
);
|
|
await dialog().getByRole('button', { name: label, exact: true }).click();
|
|
return (await request).postDataJSON();
|
|
};
|
|
try {
|
|
for (const width of [1440, 390, 320]) {
|
|
await page.setViewportSize({ width, height: 900 });
|
|
for (const theme of ['light', 'dark']) {
|
|
await page.emulateMedia({ colorScheme: theme });
|
|
await visit();
|
|
await noOverflow();
|
|
await page.screenshot({
|
|
path: '/private/tmp/kan47-' + width + '-' + theme + '.png',
|
|
fullPage: true,
|
|
});
|
|
const trigger = button('Manage members of Platform team');
|
|
await trigger.focus();
|
|
await page.keyboard.press('Enter');
|
|
await dialog().waitFor();
|
|
await page.keyboard.press('Tab');
|
|
assert.equal(
|
|
await dialog().evaluate((el) =>
|
|
el.contains(document.activeElement),
|
|
),
|
|
true,
|
|
);
|
|
await noOverflow();
|
|
await page.screenshot({
|
|
path:
|
|
'/private/tmp/kan47-members-' +
|
|
width +
|
|
'-' +
|
|
theme +
|
|
'.png',
|
|
fullPage: true,
|
|
});
|
|
await page.keyboard.press('Escape');
|
|
await dialog().waitFor({ state: 'hidden' });
|
|
assert.equal(
|
|
await trigger.evaluate((el) => document.activeElement === el),
|
|
true,
|
|
);
|
|
}
|
|
}
|
|
await visit('&manager');
|
|
assert.equal(await button('Create team').count(), 0);
|
|
await visit('&empty');
|
|
await page.getByText('No teams to manage', { exact: true }).waitFor();
|
|
await visit();
|
|
await page.getByLabel('Search teams', { exact: true }).fill('missing');
|
|
await page.getByText('No matching teams', { exact: true }).waitFor();
|
|
await button('Clear search').click();
|
|
await button('Create team').click();
|
|
await page.getByLabel('Team name', { exact: true }).fill('New team');
|
|
await result('validation');
|
|
assert.deepEqual(await save('Create team'), { name: 'New team' });
|
|
await state('validation');
|
|
assert.equal(
|
|
await page.getByLabel('Team name', { exact: true }).inputValue(),
|
|
'New team',
|
|
);
|
|
await page
|
|
.getByText('This team name is already taken.', { exact: true })
|
|
.waitFor();
|
|
await result('success');
|
|
await save('Create team');
|
|
await dialog().waitFor({ state: 'hidden' });
|
|
await page
|
|
.getByRole('heading', { name: 'New team', exact: true })
|
|
.waitFor();
|
|
|
|
await button('Manage members of Platform team').click();
|
|
const person = (name) =>
|
|
dialog().getByRole('checkbox', { name: new RegExp(name) });
|
|
await page.getByLabel('Find people').fill('sam@');
|
|
await person('Sam Taylor').check();
|
|
await page.getByLabel('Find people').fill('');
|
|
assert.equal(await person('Alex Morgan').isChecked(), true);
|
|
let dismissed = false;
|
|
page.once('dialog', async (d) => {
|
|
dismissed = true;
|
|
await d.dismiss();
|
|
});
|
|
await dialog().getByRole('button', { name: 'Cancel', exact: true }).click();
|
|
assert.equal(dismissed, true);
|
|
assert.equal(await dialog().isVisible(), true);
|
|
await result('validation');
|
|
assert.deepEqual(await save('Save members'), { user_ids: [1, 2] });
|
|
await state('validation');
|
|
await page
|
|
.getByText('This user is unavailable.', { exact: true })
|
|
.waitFor();
|
|
assert.equal(await person('Sam Taylor').isChecked(), true);
|
|
await page.route('**/teams/1/members', (route) => route.abort('failed'));
|
|
await save('Save members');
|
|
await state('network');
|
|
await page.unroute('**/teams/1/members');
|
|
await result('server');
|
|
await save('Save members');
|
|
await state('server');
|
|
await result('success');
|
|
await dialog()
|
|
.getByRole('button', { name: 'Try again', exact: true })
|
|
.click();
|
|
await dialog().waitFor({ state: 'hidden' });
|
|
await button('Manage members of Platform team').click();
|
|
await person('Alex Morgan').uncheck();
|
|
await person('Sam Taylor').uncheck();
|
|
assert.deepEqual(await save('Save members'), { user_ids: [] });
|
|
await dialog().waitFor({ state: 'hidden' });
|
|
|
|
await button('Manage permissions for Platform team').click();
|
|
assert.equal(
|
|
await dialog()
|
|
.getByRole('button', { name: 'Save permissions', exact: true })
|
|
.isDisabled(),
|
|
true,
|
|
);
|
|
await page.getByLabel('User', { exact: true }).selectOption('2');
|
|
assert.equal(await person('Team invite').isChecked(), true);
|
|
await person('Team manage').check();
|
|
page.once('dialog', (d) => d.dismiss());
|
|
await page.getByLabel('User', { exact: true }).selectOption('3');
|
|
assert.equal(
|
|
await page.getByLabel('User', { exact: true }).inputValue(),
|
|
'2',
|
|
);
|
|
await result('validation');
|
|
assert.deepEqual(await save('Save permissions'), {
|
|
permissions: ['team:invite', 'team:manage'],
|
|
});
|
|
await state('validation');
|
|
await page
|
|
.getByText('This permission is unavailable.', { exact: true })
|
|
.waitFor();
|
|
await result('forbidden');
|
|
await save('Save permissions');
|
|
await state('server');
|
|
await page
|
|
.getByText('You no longer have permission', { exact: true })
|
|
.waitFor();
|
|
assert.equal(
|
|
await dialog()
|
|
.getByRole('button', { name: 'Try again', exact: true })
|
|
.count(),
|
|
0,
|
|
);
|
|
assert.equal(await person('Team manage').isChecked(), true);
|
|
await result('success');
|
|
await save('Save permissions');
|
|
await dialog().waitFor({ state: 'hidden' });
|
|
await button('Manage permissions for Platform team').click();
|
|
await page.getByLabel('User', { exact: true }).selectOption('2');
|
|
assert.equal(await person('Team manage').isChecked(), true);
|
|
await person('Team invite').uncheck();
|
|
await person('Team manage').uncheck();
|
|
assert.deepEqual(await save('Save permissions'), { permissions: [] });
|
|
await dialog().waitFor({ state: 'hidden' });
|
|
assert.deepEqual(errors, []);
|
|
console.log(
|
|
'Teams browser checks passed: creation, membership, permissions, empty selections, validation, network/server/403, draft protection, focus, keyboard, themes and mobile.',
|
|
);
|
|
} finally {
|
|
await browser.close();
|
|
}
|