Skip to content

Commit

Permalink
feat: basic e2e test for projects
Browse files Browse the repository at this point in the history
  • Loading branch information
Leksat committed Dec 16, 2024
1 parent 73dc8e1 commit 2a9ef91
Show file tree
Hide file tree
Showing 16 changed files with 318 additions and 45 deletions.
166 changes: 129 additions & 37 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions tests/e2e-basic/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/test-results
/playwright-report
13 changes: 13 additions & 0 deletions tests/e2e-basic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Basic end-to-end tests

This package is preserved in the cloned projects. It performs very basic e2e
tests ensuring that all apps work.

It is recommended to

- Have just one test per app
- Keep tests minimal
- Make tests project-agnostic
- Not add new tests unless
- It's needed for a new app
- It's a test for a critical feature
8 changes: 8 additions & 0 deletions tests/e2e-basic/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { base, defineConfig } from '@custom/eslint-config';

export default defineConfig([
...base,
{
ignores: ['playwright-report/**', 'test-results/**'],
},
]);
22 changes: 22 additions & 0 deletions tests/e2e-basic/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "@custom-tests/e2e-basic",
"version": "1.0.0",
"description": "A very basic e2e test suite.",
"type": "module",
"scripts": {
"test:static": "tsc --noEmit && eslint . --quiet",
"test:integration": "playwright install chromium && playwright test",
"test:headed": "playwright install chromium && playwright test --headed"
},
"devDependencies": {
"@custom/cms": "workspace:*",
"@custom/decap": "workspace:*",
"@custom/eslint-config": "workspace:*",
"@custom/preview": "workspace:*",
"@custom/publisher": "workspace:*",
"@custom/website": "workspace:*",
"@playwright/test": "^1.44.1",
"@types/node": "^18",
"typescript": "^5.3.3"
}
}
43 changes: 43 additions & 0 deletions tests/e2e-basic/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
retries: process.env.CI ? 2 : 0,
workers: 1,
reporter: 'html',
use: {
trace: process.env.CI ? 'retain-on-failure' : 'on',
actionTimeout: 10_000,
},
webServer: [
{
command: 'pnpm run --filter "@custom/cms" dev >> /tmp/cms.log 2>&1',
port: 8888,
reuseExistingServer: !process.env.CI,
},
{
command:
'pnpm run --filter "@custom/publisher" dev >> /tmp/website.log 2>&1',
port: 8000,
reuseExistingServer: !process.env.CI,
},
{
command:
'pnpm run --filter "@custom/preview" start >> /tmp/preview.log 2>&1',
port: 8001,
reuseExistingServer: !process.env.CI,
},
],
testDir: './specs',
projects: [
{
name: 'setup',
testMatch: /setup\.ts/,
},
{
name: 'chromium',
testMatch: /\.*.spec\.ts/,
use: { ...devices['Desktop Chrome'] },
dependencies: ['setup'],
},
],
});
6 changes: 6 additions & 0 deletions tests/e2e-basic/specs/cms.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { expect, test } from '@playwright/test';

test('cms', async ({ page }) => {
await page.goto('http://127.0.0.1:8888');
await expect(page.getByRole('button', { name: 'Log in' })).toBeVisible();
});
9 changes: 9 additions & 0 deletions tests/e2e-basic/specs/decap.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { expect, test } from '@playwright/test';

test('decap', async ({ page }) => {
await page.goto('http://127.0.0.1:8000/admin');
await page.getByRole('button', { name: 'Login' }).click();
await expect(
page.getByRole('heading', { name: 'Collections' }),
).toBeVisible();
});
17 changes: 17 additions & 0 deletions tests/e2e-basic/specs/preview.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { expect, test } from '@playwright/test';

test('preview', async ({ page }) => {
// Login.
await page.goto('http://127.0.0.1:8888');
await page.getByLabel('Username').fill('admin');
await page.getByLabel('Password').fill('admin');
await page.getByRole('button', { name: 'Log in' }).click();
// Check the Imprint page preview.
await page.goto('http://127.0.0.1:8888/imprint');
await expect(
page
.frameLocator('iframe')
.first()
.getByRole('heading', { name: 'Imprint', exact: true }),
).toBeVisible();
});
5 changes: 5 additions & 0 deletions tests/e2e-basic/specs/publisher.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { test } from '@playwright/test';

test('publisher', async () => {
// Publisher is checked in the setup.ts.
});
35 changes: 35 additions & 0 deletions tests/e2e-basic/specs/setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { expect, test } from '@playwright/test';

const attemptDelay = 1000 * 5;
const netlifyBootTimeout = 1000 * 60 * 2;
const websiteBuildTimeout = 1000 * 60 * 2;

test.setTimeout(websiteBuildTimeout + netlifyBootTimeout + 10_000);

test('setup', async ({ page }) => {
// Wait for Publisher to build the website.
await page.goto('http://127.0.0.1:8000/___status');
await expect(page.getByText('Status: Ready')).toBeVisible({
timeout: websiteBuildTimeout,
});

// Wait for Netlify to boot.
// When "netlify dev" starts, the port check reports it's working, yet the
// first page load takes a long time - Netlify downloads Deno and packages
// (sometimes at a very slow speed). Nothing really works until this is done.
// This might fail tests. So we try to load the website frontpage first.
let success = false;
const timeoutId = setTimeout(() => {
throw new Error(
`"netlify dev" failed to start in ${netlifyBootTimeout}ms. Check /tmp/website.log for details.`,
);
}, netlifyBootTimeout);
while (!success) {
try {
await page.goto('http://127.0.0.1:8000', { timeout: attemptDelay });
clearTimeout(timeoutId);
success = true;
// eslint-disable-next-line @typescript-eslint/no-unused-vars,no-empty
} catch (e) {}
}
});
7 changes: 7 additions & 0 deletions tests/e2e-basic/specs/website.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { expect, test } from '@playwright/test';

test('website', async ({ page }) => {
await page.goto('http://127.0.0.1:8000');
await expect(page.locator('h1')).toBeVisible();
await expect(page.getByText(/error/i)).not.toBeVisible();
});
6 changes: 6 additions & 0 deletions tests/e2e-basic/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"compilerOptions": {
"strict": true,
"skipLibCheck": true
}
}
12 changes: 12 additions & 0 deletions tests/e2e-basic/turbo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"extends": ["//"],
"tasks": {
"test:static": {
"inputs": ["specs/**", "playwright.config.ts"]
},
"test:integration": {
"dependsOn": ["^prep"],
"inputs": ["specs/**", "playwright.config.ts"]
}
}
}
4 changes: 4 additions & 0 deletions tests/e2e/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# End-to-end tests for the template

This package is deleted in the cloned projects. It is used to test the template
itself, not the cloned projects.
8 changes: 0 additions & 8 deletions tests/e2e/specs/decap/admin.spec.ts

This file was deleted.

0 comments on commit 2a9ef91

Please sign in to comment.