Skip to content

Commit

Permalink
Enabled 'parallel' mode for all Playwright test files
Browse files Browse the repository at this point in the history
And added testing for `/blog/272`.
  • Loading branch information
EthanThatOneKid committed Oct 12, 2022
1 parent 2200482 commit b199949
Show file tree
Hide file tree
Showing 20 changed files with 129 additions and 47 deletions.
30 changes: 15 additions & 15 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -27,7 +27,7 @@
"all": "npm run lint && npm run format && npm run check && npm run build && npm t"
},
"devDependencies": {
"@playwright/test": "^1.27.0",
"@playwright/test": "^1.28.0-alpha-oct-12-2022",
"@size-limit/file": "^8.1.0",
"@sveltejs/adapter-auto": "next",
"@sveltejs/kit": "next",
Expand Down
20 changes: 13 additions & 7 deletions playwright.config.ts
Expand Up @@ -27,9 +27,13 @@ const config: PlaywrightTestConfig = {
outputDir: '.playwright_output',
};

export default config;

function projectsFromMatrix<
/**
* projectsFromMatrix is a helper function that returns an array of projects
* based on a matrix of dimensions. Each dimension is an object with a name
* and a value. The name is used to name the project, and the value is used
* to set the project's use property.
*/
export function projectsFromMatrix<
TestArgs = PlaywrightTestOptions,
WorkerArgs = PlaywrightWorkerOptions,
ProjectArgs = Project<TestArgs, WorkerArgs>['use']
Expand All @@ -40,12 +44,12 @@ function projectsFromMatrix<
const combinations: Project<TestArgs, WorkerArgs>[] = [];

for (let i = 0; i < propNames.length; i++) {
const propName = propNames[i];
const dimensionNames = Object.keys(matrix[propNames[i]]);
const propName = propNames[i] as keyof Partial<ProjectArgs>;
const dimensionNames = Object.keys(matrix[propName]);

for (let j = i + 1; j < propNames.length; j++) {
const propName2 = propNames[j];
const dimensionNames2 = Object.keys(matrix[propNames[j]]);
const propName2 = propNames[j] as keyof Partial<ProjectArgs>;
const dimensionNames2 = Object.keys(matrix[propName2]);

for (const dimensionName of dimensionNames) {
for (const dimensionName2 of dimensionNames2) {
Expand All @@ -67,3 +71,5 @@ function projectsFromMatrix<

return combinations;
}

export default config;
2 changes: 2 additions & 0 deletions src/routes/(site)/1st/page.test.ts
@@ -1,5 +1,7 @@
import { expect, test } from '@playwright/test';

test.describe.configure({ mode: 'parallel' });

test('first contributions page has expected h1', async ({ page }) => {
await page.goto('/1st');
expect(await page.textContent('h1')).toBe('First Contributions');
Expand Down
2 changes: 2 additions & 0 deletions src/routes/(site)/about/page.test.ts
@@ -1,5 +1,7 @@
import { expect, test } from '@playwright/test';

test.describe.configure({ mode: 'parallel' });

test('about page has expected h1', async ({ page }) => {
await page.goto('/about');
expect(await page.textContent('h1')).toBe('About us');
Expand Down
57 changes: 57 additions & 0 deletions src/routes/(site)/blog/[id]/page.test.ts
@@ -0,0 +1,57 @@
import type { TestInfo } from '@playwright/test';
import { expect, test } from '@playwright/test';
import path from 'node:path';

test.describe.configure({ mode: 'parallel' });

// setupSnapshot is a helper that creates handles the necessary boilerplate
// for snapshot testing. It returns a function that can be called after the
// snapshot test has executed.
//
// See:
// https://github.com/microsoft/playwright/issues/14527#issuecomment-1143352769
export function setupSnapshot(testInfo: TestInfo) {
const snapshotDir = testInfo.snapshotDir;
const snapshotSuffix = testInfo.snapshotSuffix;
const projectName = testInfo.project.name;

testInfo.snapshotDir = path.resolve(snapshotDir, '..', 'screenshots');
testInfo.snapshotSuffix = '';
testInfo.project.name = '';

return {
data: { projectName },
cleanupSnapshot() {
testInfo.snapshotDir = snapshotDir;
testInfo.snapshotSuffix = snapshotSuffix;
testInfo.project.name = projectName;
},
};
}

test('blog post h1 matches page title', async ({ page }) => {
await page.goto('/blog/272');
expect(await page.title()).toContain(await page.textContent('h1'));
});

test('blog post page matches screenshot', async ({ page }, testInfo) => {
const { cleanupSnapshot, data } = setupSnapshot(testInfo);

if (testInfo.project.use.viewport) {
await page.setViewportSize(testInfo.project.use.viewport);
}

if (testInfo.project.use.colorScheme) {
await page.emulateMedia({
colorScheme: testInfo.project.use.colorScheme,
});
}

await page.goto('/blog/272');
expect(await page.screenshot({ fullPage: true, scale: 'css' })).toMatchSnapshot({
name: `page-${data.projectName}.png`,
threshold: 0.1,
});

cleanupSnapshot();
});
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/routes/(site)/blog/page.test.ts
@@ -1,5 +1,7 @@
import { expect, test } from '@playwright/test';

test.describe.configure({ mode: 'parallel' });

test('blog page has expected h1', async ({ page }) => {
await page.goto('/blog');
expect(await page.textContent('h1')).toBe('README');
Expand Down
2 changes: 2 additions & 0 deletions src/routes/(site)/nodebuds/page.test.ts
@@ -1,5 +1,7 @@
import { expect, test } from '@playwright/test';

test.describe.configure({ mode: 'parallel' });

test('nodebuds page has expected h1', async ({ page }) => {
await page.goto('/nodebuds');
expect(await page.textContent('h1')).toBe('Personalized for your success');
Expand Down
5 changes: 3 additions & 2 deletions src/routes/(site)/page.test.ts
@@ -1,9 +1,10 @@
import { expect, test } from '@playwright/test';

test.describe.configure({ mode: 'parallel' });

test('index page has expected h1', async ({ page }) => {
await page.goto('/');

const h1 = await page.locator('h1');
const textContext = await h1.textContent();
const textContext = await page.locator('h1').textContent();
expect(textContext).toContain('largest computer science community');
});
2 changes: 2 additions & 0 deletions src/routes/(site)/privacy/page.test.ts
@@ -1,5 +1,7 @@
import { expect, test } from '@playwright/test';

test.describe.configure({ mode: 'parallel' });

test('privacy page has expected h1', async ({ page }) => {
await page.goto('/privacy');
expect(await page.textContent('h1')).toBe('Privacy Policy');
Expand Down
2 changes: 2 additions & 0 deletions src/routes/(site)/quiz/page.test.ts
@@ -1,5 +1,7 @@
import { expect, test } from '@playwright/test';

test.describe.configure({ mode: 'parallel' });

test('quiz page has expected h1', async ({ page }) => {
await page.goto('/quiz');
expect(await page.textContent('h1')).toBe('ACM TEAM QUIZ');
Expand Down
2 changes: 2 additions & 0 deletions src/routes/(site)/teams/page.test.ts
@@ -1,5 +1,7 @@
import { expect, test } from '@playwright/test';

test.describe.configure({ mode: 'parallel' });

test('teams page has expected h1', async ({ page }) => {
await page.goto('/teams');
expect(await page.textContent('h1')).toBe('Meet the Teams');
Expand Down
2 changes: 1 addition & 1 deletion src/routes/+layout.svelte
Expand Up @@ -11,7 +11,7 @@
$: if (browser) {
send({
id: "$VERCEL_ANALYTICS_ID",
id: '$VERCEL_ANALYTICS_ID',
path: $page.url.pathname,
params: $page.params,
navigator,
Expand Down
46 changes: 25 additions & 21 deletions src/routes/error.test.ts
Expand Up @@ -4,6 +4,31 @@ import path from 'node:path';

test.describe.configure({ mode: 'parallel' });

// setupSnapshot is a helper that creates handles the necessary boilerplate
// for snapshot testing. It returns a function that can be called after the
// snapshot test has executed.
//
// See:
// https://github.com/microsoft/playwright/issues/14527#issuecomment-1143352769
export function setupSnapshot(testInfo: TestInfo) {
const snapshotDir = testInfo.snapshotDir;
const snapshotSuffix = testInfo.snapshotSuffix;
const projectName = testInfo.project.name;

testInfo.snapshotDir = path.resolve(snapshotDir, '..', 'screenshots');
testInfo.snapshotSuffix = '';
testInfo.project.name = '';

return {
data: { projectName },
cleanupSnapshot() {
testInfo.snapshotDir = snapshotDir;
testInfo.snapshotSuffix = snapshotSuffix;
testInfo.project.name = projectName;
},
};
}

test('error page has expected em', async ({ page }) => {
await page.goto('/this-page/does-not/exist');
expect(await page.textContent('em')).toBe('404');
Expand Down Expand Up @@ -31,24 +56,3 @@ test('error page matches screenshot', async ({ page }, testInfo) => {

cleanupSnapshot();
});

// See:
// https://github.com/microsoft/playwright/issues/14527#issuecomment-1143352769
function setupSnapshot(testInfo: TestInfo) {
const snapshotDir = testInfo.snapshotDir;
const snapshotSuffix = testInfo.snapshotSuffix;
const projectName = testInfo.project.name;

testInfo.snapshotDir = path.resolve(snapshotDir, '..', 'screenshots');
testInfo.snapshotSuffix = '';
testInfo.project.name = '';

return {
data: { projectName },
cleanupSnapshot() {
testInfo.snapshotDir = snapshotDir;
testInfo.snapshotSuffix = snapshotSuffix;
testInfo.project.name = projectName;
},
};
}

0 comments on commit b199949

Please sign in to comment.