Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8abbca1b41 | |||
| d62ce26759 | |||
| faf5269eba | |||
| 9a20cc009d | |||
| 6891f87447 | |||
| 17633f3345 | |||
| 59e7194cf7 |
@@ -44,3 +44,6 @@ public/sitemap-0.xml
|
||||
|
||||
# Sentry
|
||||
.sentryclirc
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/playwright/.cache/
|
||||
|
||||
+1
-1
@@ -25,5 +25,5 @@ module.exports = withBundleAnalyzer(withSentryConfig({
|
||||
},
|
||||
sentry: {
|
||||
hideSourceMaps: true, // Hide source maps, see: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-source-maps
|
||||
}
|
||||
},
|
||||
}, sentryWebpackPluginOptions));
|
||||
|
||||
Generated
+690
-494
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -28,12 +28,13 @@
|
||||
"start-prod": "next start --port ${SERVER_PORT:=80}",
|
||||
"serve": "next start --port 3000",
|
||||
"test:unit": "jest --coverage",
|
||||
"test": "npm run testcafe",
|
||||
"test": "playwright test",
|
||||
"testcafe": "testcafe --config-file testcafe.json",
|
||||
"build-analyze": "ANALYZE=true npm run build",
|
||||
"prepare": "husky install"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.38.1",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/js-cookie": "^3.0.1",
|
||||
"@types/node": "^16.11.36",
|
||||
|
||||
@@ -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,
|
||||
// },
|
||||
});
|
||||
@@ -15,6 +15,8 @@
|
||||
"ja hallitukset kuulumiset": "and what the board has been up to",
|
||||
"Kuvia tapahtumista": "Photos from events",
|
||||
"kuvagalleriassa": "in the photo gallery",
|
||||
"Lisää killan": "Add guild's",
|
||||
"Google-kalenteri": "Google-calendar",
|
||||
|
||||
"Hakemaasi sivua":
|
||||
"Page",
|
||||
@@ -51,6 +53,9 @@
|
||||
"Ilmoittautuminen sulkeutuu":
|
||||
"Signup closes at",
|
||||
|
||||
"Ilmoittautuminen onnistui!":
|
||||
"Signup successful!",
|
||||
|
||||
"Ilmoittauminen on umpeutunut!":
|
||||
"Signup has been closed!",
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import { NextPage, GetStaticProps, GetStaticPaths } from "next";
|
||||
import Head from "next/head";
|
||||
import { useRouter } from "next/router";
|
||||
import { ISubmitEvent } from "@rjsf/core";
|
||||
import { toast } from "react-toastify";
|
||||
import axios from "axios";
|
||||
import useSWR, { mutate } from "swr";
|
||||
import useSWR from "swr";
|
||||
import { Signup, SignupForm } from "@models/Signup";
|
||||
import SignupApi from "@api/signupApi";
|
||||
import SignUpPageView from "@views/SignUpPage/SignUpPageView";
|
||||
@@ -25,6 +25,8 @@ const SignUpPage: NextPage<InitialProps> = ({ initialForm }) => {
|
||||
const id = String(initialForm?.id ?? "");
|
||||
const URL = `${FORM_URL}${id}/`;
|
||||
const { data: signupForm, error } = useSWR<SignupForm>(URL, (url) => axios.get(url).then((res) => res.data), { fallbackData: initialForm });
|
||||
const [isSending, setIsSending] = useState(false);
|
||||
const [formSent, setFormSent] = useState(false);
|
||||
|
||||
if (error) {
|
||||
console.error(error);
|
||||
@@ -42,18 +44,26 @@ const SignUpPage: NextPage<InitialProps> = ({ initialForm }) => {
|
||||
}
|
||||
|
||||
const onSubmit = async ({ formData }: ISubmitEvent<string>) => {
|
||||
setIsSending(true);
|
||||
|
||||
const payload: Signup = {
|
||||
signupForm_id: signupForm.id,
|
||||
answer: formData,
|
||||
};
|
||||
|
||||
if (isSending === true) {
|
||||
toast.error("Sign-up form already submitted! No need to spam send. 😟");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await SignupApi.createSignup(payload);
|
||||
toast.success("Sign-up submitted successfully 😎");
|
||||
mutate(URL);
|
||||
setFormSent(true);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
toast.error("Uh oh! Sign-up failed! 😟");
|
||||
setIsSending(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -68,6 +78,7 @@ const SignUpPage: NextPage<InitialProps> = ({ initialForm }) => {
|
||||
formData={{}}
|
||||
onChange={noop}
|
||||
onSubmit={onSubmit}
|
||||
formSent={formSent}
|
||||
/>
|
||||
</PageWrapper>
|
||||
</>
|
||||
|
||||
@@ -186,6 +186,8 @@ const InEnglishPageView: React.FC<InEnglishPageViewProps> = ({ events, feed }) =
|
||||
<h3 id="freshmen">For exchange student</h3>
|
||||
<div>
|
||||
<div>
|
||||
<h6>Telegram group 2023-2024</h6>
|
||||
<p>For starters, we recommend you join the <Link to="https://t.me/+ewiOhvuTXAcwODRk">Telegram-channel</Link> made for new exchange and master's students.</p>
|
||||
<h6>Freshman points</h6>
|
||||
<p>What is student life like in Finland? What are the unique cool things to experience? To find out we recommend collecting the fuksi points (freshman points) to your fuksi point card. It's fun! The point card gives you a guideline to experiencing the student life and allows you to get a diploma with the privilege to wear the teekkari cap. Note that internationals are also fuksis on their first year in Aalto even though they are not really freshmen. Even Finns who change to a different study program get to be a fuksi again.</p>
|
||||
<h6>Overalls</h6>
|
||||
|
||||
@@ -23,6 +23,7 @@ interface SignUpPageViewProps {
|
||||
formData: any;
|
||||
onChange: (e: IChangeEvent<unknown>, es?: ErrorSchema) => unknown;
|
||||
onSubmit: (e: ISubmitEvent<unknown>) => unknown;
|
||||
formSent?: boolean;
|
||||
}
|
||||
|
||||
const StyledSection = styled(TextSection)`
|
||||
@@ -59,6 +60,7 @@ const SignUpPageView: React.FC<SignUpPageViewProps> = ({
|
||||
formData,
|
||||
onChange,
|
||||
onSubmit,
|
||||
formSent = false,
|
||||
}) => {
|
||||
const { i18n, t } = useTranslation();
|
||||
const startDate = new Date(signUpForm?.start_time);
|
||||
@@ -136,7 +138,7 @@ const SignUpPageView: React.FC<SignUpPageViewProps> = ({
|
||||
</h1>
|
||||
|
||||
<div>
|
||||
{form}
|
||||
{ formSent ? <p>{`${t("Ilmoittautuminen onnistui!")}`}</p> : form }
|
||||
</div>
|
||||
{signups}
|
||||
</StyledSection>
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
@@ -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);
|
||||
});
|
||||
@@ -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 |
@@ -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,5 +1,5 @@
|
||||
import { Selector } from "testcafe";
|
||||
import { getSiteRoot } from "./utils";
|
||||
import { getSiteRoot } from "../utils";
|
||||
|
||||
fixture`404 page renders and functions correctly`.page(`${getSiteRoot()}/404`);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Selector } from "testcafe";
|
||||
import {
|
||||
getSiteRoot, getPageUrl, generateTestForm, deleteEvent, deleteForm, doLogin, generateAccessToken, getPostRequestLogger, waitForLogger,
|
||||
} from "../utils";
|
||||
} from "../../utils";
|
||||
|
||||
const LOGGER = getPostRequestLogger("events/");
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Selector } from "testcafe";
|
||||
import {
|
||||
getSiteRoot, getPageUrl, deleteForm, doLogin, generateAccessToken, getPostRequestLogger, waitForLogger
|
||||
} from "../utils";
|
||||
} from "../../utils";
|
||||
|
||||
const LOGGER = getPostRequestLogger("signupForm/");
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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`);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Selector } from "testcafe";
|
||||
import { getSiteRoot } from "./utils";
|
||||
import { getSiteRoot } from "../utils";
|
||||
|
||||
fixture`Front page renders and functions correctly`.page(`${getSiteRoot()}`);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Selector } from "testcafe";
|
||||
import {
|
||||
getSiteRoot, getPageUrl, generateTestEvent, generateTestForm, deleteEvent, deleteForm, generateAccessToken,
|
||||
} from "./utils";
|
||||
} from "../utils";
|
||||
|
||||
fixture`Event signup`.page(getSiteRoot())
|
||||
.before(async (ctx) => {
|
||||
|
||||
@@ -156,13 +156,15 @@ export const generateTestEvent = async (formIds = [], jwt_access: string) => (
|
||||
}, 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) => {
|
||||
for (let i = 0; i < 50; i++) {
|
||||
await sleep(100);
|
||||
if (logger.requests.length > 0 ) {
|
||||
return;
|
||||
let i = 0;
|
||||
while (i < 50) {
|
||||
await sleep(100); // eslint-disable-line no-await-in-loop
|
||||
if (logger.requests.length > 0) {
|
||||
return;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
+4
-3
@@ -58,11 +58,12 @@
|
||||
"include": [
|
||||
"./src/**/*",
|
||||
"./types/**/*",
|
||||
"./tests/testcafe/**/*",
|
||||
"./tests/**/*",
|
||||
".eslintrc.js",
|
||||
"jest.config.js",
|
||||
"next-sitemap.config.js",
|
||||
"next.config.js",
|
||||
"jest.config.js",
|
||||
".eslintrc.js",
|
||||
"playwright.config.ts",
|
||||
"sentry.client.config.js",
|
||||
"sentry.server.config.js"
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user