Compare commits

...

1 Commits

Author SHA1 Message Date
Aarni Halinen 8abbca1b41 Install playwright 2023-10-03 20:59:42 +03:00
20 changed files with 262 additions and 16 deletions
+3
View File
@@ -44,3 +44,6 @@ public/sitemap-0.xml
# Sentry # Sentry
.sentryclirc .sentryclirc
/test-results/
/playwright-report/
/playwright/.cache/
+71
View File
@@ -37,6 +37,7 @@
"swr": "^1.2.2" "swr": "^1.2.2"
}, },
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.38.1",
"@types/jest": "^27.4.1", "@types/jest": "^27.4.1",
"@types/js-cookie": "^3.0.1", "@types/js-cookie": "^3.0.1",
"@types/node": "^16.11.36", "@types/node": "^16.11.36",
@@ -2723,6 +2724,21 @@
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==",
"dev": true "dev": true
}, },
"node_modules/@playwright/test": {
"version": "1.38.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.38.1.tgz",
"integrity": "sha512-NqRp8XMwj3AK+zKLbZShl0r/9wKgzqI/527bkptKXomtuo+dOjU9NdMASQ8DNC9z9zLOMbG53T4eihYr3XR+BQ==",
"dev": true,
"dependencies": {
"playwright": "1.38.1"
},
"bin": {
"playwright": "cli.js"
},
"engines": {
"node": ">=16"
}
},
"node_modules/@polka/url": { "node_modules/@polka/url": {
"version": "1.0.0-next.21", "version": "1.0.0-next.21",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz",
@@ -11199,6 +11215,36 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/playwright": {
"version": "1.38.1",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.38.1.tgz",
"integrity": "sha512-oRMSJmZrOu1FP5iu3UrCx8JEFRIMxLDM0c/3o4bpzU5Tz97BypefWf7TuTNPWeCe279TPal5RtPPZ+9lW/Qkow==",
"dev": true,
"dependencies": {
"playwright-core": "1.38.1"
},
"bin": {
"playwright": "cli.js"
},
"engines": {
"node": ">=16"
},
"optionalDependencies": {
"fsevents": "2.3.2"
}
},
"node_modules/playwright-core": {
"version": "1.38.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.38.1.tgz",
"integrity": "sha512-tQqNFUKa3OfMf4b2jQ7aGLB8o9bS3bOY0yMEtldtC2+spf8QXG9zvXLTXUeRsoNuxEYMgLYR+NXfAa1rjKRcrg==",
"dev": true,
"bin": {
"playwright-core": "cli.js"
},
"engines": {
"node": ">=16"
}
},
"node_modules/pngjs": { "node_modules/pngjs": {
"version": "3.4.0", "version": "3.4.0",
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz",
@@ -17049,6 +17095,15 @@
} }
} }
}, },
"@playwright/test": {
"version": "1.38.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.38.1.tgz",
"integrity": "sha512-NqRp8XMwj3AK+zKLbZShl0r/9wKgzqI/527bkptKXomtuo+dOjU9NdMASQ8DNC9z9zLOMbG53T4eihYr3XR+BQ==",
"dev": true,
"requires": {
"playwright": "1.38.1"
}
},
"@polka/url": { "@polka/url": {
"version": "1.0.0-next.21", "version": "1.0.0-next.21",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz",
@@ -23383,6 +23438,22 @@
} }
} }
}, },
"playwright": {
"version": "1.38.1",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.38.1.tgz",
"integrity": "sha512-oRMSJmZrOu1FP5iu3UrCx8JEFRIMxLDM0c/3o4bpzU5Tz97BypefWf7TuTNPWeCe279TPal5RtPPZ+9lW/Qkow==",
"dev": true,
"requires": {
"fsevents": "2.3.2",
"playwright-core": "1.38.1"
}
},
"playwright-core": {
"version": "1.38.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.38.1.tgz",
"integrity": "sha512-tQqNFUKa3OfMf4b2jQ7aGLB8o9bS3bOY0yMEtldtC2+spf8QXG9zvXLTXUeRsoNuxEYMgLYR+NXfAa1rjKRcrg==",
"dev": true
},
"pngjs": { "pngjs": {
"version": "3.4.0", "version": "3.4.0",
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz",
+2 -1
View File
@@ -28,12 +28,13 @@
"start-prod": "next start --port ${SERVER_PORT:=80}", "start-prod": "next start --port ${SERVER_PORT:=80}",
"serve": "next start --port 3000", "serve": "next start --port 3000",
"test:unit": "jest --coverage", "test:unit": "jest --coverage",
"test": "npm run testcafe", "test": "playwright test",
"testcafe": "testcafe --config-file testcafe.json", "testcafe": "testcafe --config-file testcafe.json",
"build-analyze": "ANALYZE=true npm run build", "build-analyze": "ANALYZE=true npm run build",
"prepare": "husky install" "prepare": "husky install"
}, },
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.38.1",
"@types/jest": "^27.4.1", "@types/jest": "^27.4.1",
"@types/js-cookie": "^3.0.1", "@types/js-cookie": "^3.0.1",
"@types/node": "^16.11.36", "@types/node": "^16.11.36",
+104
View File
@@ -0,0 +1,104 @@
import { defineConfig, devices } from "@playwright/test";
/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config();
/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: "./tests/playwright",
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: "html",
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: "https://dev.sahkoinsinoorikilta.fi",
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: "on-first-retry",
},
/* Configure projects for major browsers */
projects: [
{
name: "event setup",
testMatch: /event-setup\.test\.ts/,
},
{
name: "test teardown",
testMatch: /event-teardown\.test\.ts/,
},
{
name: "tests",
testIgnore: /admin\//,
dependencies: ["event setup"],
teardown: "test teardown",
use: { ...devices["Desktop Chrome"] },
},
{
name: "admin setup",
testMatch: /admin\/setup\.test\.ts/,
},
{
name: "admin tests",
testDir: "/tests/playwright/admin",
testIgnore: /admin\/setup\.test\.ts/,
dependencies: ["admin setup"],
use: { ...devices["Desktop Chrome"] },
},
// {
// name: "chromium",
// use: { ...devices["Desktop Chrome"] },
// },
// {
// name: "firefox",
// use: { ...devices["Desktop Firefox"] },
// },
// {
// name: "webkit",
// use: { ...devices["Desktop Safari"] },
// },
// /* Test against mobile viewports. */
// {
// name: "Mobile Chrome",
// use: { ...devices["Pixel 5"] },
// },
// {
// name: "Mobile Safari",
// use: { ...devices["iPhone 12"] },
// },
// /* Test against branded browsers. */
// {
// name: "Microsoft Edge",
// use: { ...devices["Desktop Edge"], channel: "msedge" },
// },
// {
// name: "Google Chrome",
// use: { ...devices["Desktop Chrome"], channel: "chrome" },
// },
],
/* Run your local dev server before starting the tests */
// webServer: {
// command: 'npm run start',
// url: 'http://127.0.0.1:3000',
// reuseExistingServer: !process.env.CI,
// },
});
+11
View File
@@ -0,0 +1,11 @@
import { test as setup } from "@playwright/test";
import { generateAccessToken, generateTestEvent, generateTestForm } from "../utils";
setup("create events", async () => {
const token = await generateAccessToken();
const form = await generateTestForm(token);
const event = await generateTestEvent([form.id], token);
process.env.FORM_ID = form.id;
process.env.EVENT_ID = event.id;
});
+10
View File
@@ -0,0 +1,10 @@
import { test as teardown } from "@playwright/test";
import { deleteEvent, deleteForm, generateAccessToken } from "../utils";
teardown("delete events", async () => {
const token = await generateAccessToken();
const { FORM_ID: formId, EVENT_ID: eventId } = process.env;
await deleteEvent(eventId, token);
await deleteForm(formId, token);
});
+24
View File
@@ -0,0 +1,24 @@
import { test, expect } from "@playwright/test";
// import fs from "fs";
// const sitemap = fs.readFileSync("../../public/sitemap-0.xml");
// const pages = sitemap.;
// test("favicon exists", async ({ page }) => {
// await page.goto("/");
// });
// Page
// const pagePath = "/";
test("landing page renders correctly", async ({ page }) => {
await page.goto("/");
await expect(page).toHaveTitle("Aalto-yliopiston Sähköinsinöörikilta ry");
await expect(page).toHaveScreenshot("index-page.png");
});
test("404 page renders correctly", async ({ page }) => {
await page.goto("/404");
await expect(page).toHaveScreenshot("404 page.png");
});
Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

+19
View File
@@ -0,0 +1,19 @@
import {
test, expect,
} from "@playwright/test";
const NAME = "Testi Testeri";
const EMAIL = "e2e@sahkoinsinoorikilta.fi";
test("signup to event", async ({ page }) => {
await page.goto("/");
await page.locator("[id=\"\\#events\"]").getByRole("button", { name: "Lue lisää " }).first().click();
await page.locator("button").filter({ hasText: "Finland flag" }).click();
await page.getByRole("button", { name: "Test" }).click();
await page.getByLabel("Nimi*").fill(NAME);
await page.getByLabel("S-Posti*").fill(EMAIL);
await page.locator("label").filter({ hasText: "Testaaja" }).locator("span").click();
await page.getByRole("button", { name: "Submit" }).click();
// await expect(page.getByText("Sign-up submitted successfully 😎")).toBeVisible();
await expect(page.getByRole("list")).toHaveText(NAME);
});
+1 -1
View File
@@ -1,5 +1,5 @@
import { Selector } from "testcafe"; import { Selector } from "testcafe";
import { getSiteRoot } from "./utils"; import { getSiteRoot } from "../utils";
fixture`404 page renders and functions correctly`.page(`${getSiteRoot()}/404`); fixture`404 page renders and functions correctly`.page(`${getSiteRoot()}/404`);
+1 -1
View File
@@ -1,7 +1,7 @@
import { Selector } from "testcafe"; import { Selector } from "testcafe";
import { import {
getSiteRoot, getPageUrl, generateTestForm, deleteEvent, deleteForm, doLogin, generateAccessToken, getPostRequestLogger, waitForLogger, getSiteRoot, getPageUrl, generateTestForm, deleteEvent, deleteForm, doLogin, generateAccessToken, getPostRequestLogger, waitForLogger,
} from "../utils"; } from "../../utils";
const LOGGER = getPostRequestLogger("events/"); const LOGGER = getPostRequestLogger("events/");
+1 -1
View File
@@ -1,7 +1,7 @@
import { Selector } from "testcafe"; import { Selector } from "testcafe";
import { import {
getSiteRoot, getPageUrl, deleteForm, doLogin, generateAccessToken, getPostRequestLogger, waitForLogger getSiteRoot, getPageUrl, deleteForm, doLogin, generateAccessToken, getPostRequestLogger, waitForLogger
} from "../utils"; } from "../../utils";
const LOGGER = getPostRequestLogger("signupForm/"); const LOGGER = getPostRequestLogger("signupForm/");
+1 -1
View File
@@ -1,5 +1,5 @@
import { Selector, ClientFunction } from "testcafe"; import { Selector, ClientFunction } from "testcafe";
import { getSiteRoot, doLogin } from "../utils"; import { getSiteRoot, doLogin } from "../../utils";
fixture`Admin login page functions correctly`.page(`${getSiteRoot()}/admin/login`); fixture`Admin login page functions correctly`.page(`${getSiteRoot()}/admin/login`);
+1 -1
View File
@@ -1,5 +1,5 @@
import { Selector } from "testcafe"; import { Selector } from "testcafe";
import { getSiteRoot } from "./utils"; import { getSiteRoot } from "../utils";
fixture`Front page renders and functions correctly`.page(`${getSiteRoot()}`); fixture`Front page renders and functions correctly`.page(`${getSiteRoot()}`);
+1 -1
View File
@@ -1,7 +1,7 @@
import { Selector } from "testcafe"; import { Selector } from "testcafe";
import { import {
getSiteRoot, getPageUrl, generateTestEvent, generateTestForm, deleteEvent, deleteForm, generateAccessToken, getSiteRoot, getPageUrl, generateTestEvent, generateTestForm, deleteEvent, deleteForm, generateAccessToken,
} from "./utils"; } from "../utils";
fixture`Event signup`.page(getSiteRoot()) fixture`Event signup`.page(getSiteRoot())
.before(async (ctx) => { .before(async (ctx) => {
+7 -5
View File
@@ -156,13 +156,15 @@ export const generateTestEvent = async (formIds = [], jwt_access: string) => (
}, jwt_access) }, jwt_access)
); );
export const sleep = async (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); export const sleep = async (ms: number) => new Promise((resolve) => { setTimeout(resolve, ms); });
export const waitForLogger = async (logger: RequestLogger) => { export const waitForLogger = async (logger: RequestLogger) => {
for (let i = 0; i < 50; i++) { let i = 0;
await sleep(100); while (i < 50) {
if (logger.requests.length > 0 ) { await sleep(100); // eslint-disable-line no-await-in-loop
if (logger.requests.length > 0) {
return; return;
} }
i += 1;
} }
} };
+4 -3
View File
@@ -58,11 +58,12 @@
"include": [ "include": [
"./src/**/*", "./src/**/*",
"./types/**/*", "./types/**/*",
"./tests/testcafe/**/*", "./tests/**/*",
".eslintrc.js",
"jest.config.js",
"next-sitemap.config.js", "next-sitemap.config.js",
"next.config.js", "next.config.js",
"jest.config.js", "playwright.config.ts",
".eslintrc.js",
"sentry.client.config.js", "sentry.client.config.js",
"sentry.server.config.js" "sentry.server.config.js"
], ],