Fix tests

This commit is contained in:
aronmal 2023-09-04 19:51:25 +02:00
parent 8e4c11570a
commit 129e36a6f2
Signed by: aronmal
GPG key ID: 816B7707426FC612
14 changed files with 804 additions and 801 deletions

View file

@ -18,12 +18,12 @@ jobs:
- name: Install Node.js - name: Install Node.js
uses: actions/setup-node@v3 uses: actions/setup-node@v3
with: with:
node-version: 18 node-version: 20
- uses: pnpm/action-setup@v2 - uses: pnpm/action-setup@v2
name: Install pnpm name: Install pnpm
with: with:
version: 8.6.10 version: 8.7.4
run_install: false run_install: false
- name: Get pnpm store directory - name: Get pnpm store directory
@ -41,8 +41,8 @@ jobs:
- name: Add FA token - name: Add FA token
run: | run: |
echo "@fortawesome:registry=https://npm.fontawesome.com/" > .npmrc npm config set "@fortawesome:registry" "https://npm.fontawesome.com/"
npm config set '//npm.fontawesome.com/:_authToken' "${{ secrets.FONTAWESOME_NPM_AUTH_TOKEN }}" npm config set "//npm.fontawesome.com/:_authToken" "${{ secrets.FONTAWESOME_NPM_AUTH_TOKEN }}"
- name: Install dependencies - name: Install dependencies
run: pnpm install --frozen-lockfile run: pnpm install --frozen-lockfile

View file

@ -1,6 +1,5 @@
import { expect, test, type BrowserContext, type Page } from "@playwright/test" import { expect, test, type BrowserContext, type Page } from "@playwright/test"
const callbackUrl = process.env.AUTH_URL as string
let context: BrowserContext let context: BrowserContext
let page: Page let page: Page
@ -16,36 +15,36 @@ test.describe.serial("Check Azure AD auth", () => {
}) })
test("Login process...", async () => { test("Login process...", async () => {
await page.goto(callbackUrl + "/signin") await page.goto("/signin")
await page.waitForLoadState("domcontentloaded") await page.locator("button#microsoft").click()
await page.click("button#microsoft")
// Indicates email can be filled in // Indicates email can be filled in
await page.waitForSelector("a#cantAccessAccount") await page.waitForSelector("a#cantAccessAccount")
// Fill email input // Fill email input
await page.fill("input#i0116", process.env.AUTH_EMAIL ?? "") await page.locator("input#i0116").fill(process.env.AUTH_EMAIL!)
// Click the "Next" button // Click the "Next" button
await page.click("input#idSIButton9") await page.locator("input#idSIButton9").click()
// Indicates password can be filled in // Indicates password can be filled in
await page.waitForSelector("a#idA_PWD_ForgotPassword") await page.waitForSelector("a#idA_PWD_ForgotPassword")
// Fill password input // Fill password input
await page.fill("input#i0118", process.env.AUTH_PW ?? "") await page.locator("input#i0118").fill(process.env.AUTH_PW!)
// Click the "Sign in" button // Click the "Sign in" button
await page.click("input#idSIButton9") await page.locator("input#idSIButton9").click()
// Click the "No" button // Click the "No" button
await page.click("input#idBtn_Back") await page.locator("input#idBtn_Back").click()
await page.waitForSelector("#start") await page.waitForSelector("#start")
}) })
test("Is logged in", async () => { test("Is logged in", async () => {
await page.goto(callbackUrl + "/api/auth/check") await page.goto("/signin")
await page.waitForSelector("button#signout")
await page.goto("/")
await page.waitForSelector("#start") await page.waitForSelector("#start")
await page.evaluate(() => document.fonts.ready) await page.evaluate(() => document.fonts.ready)
@ -55,11 +54,9 @@ test.describe.serial("Check Azure AD auth", () => {
}) })
test("Is logged out", async () => { test("Is logged out", async () => {
await page.goto(callbackUrl + "/signout") await page.goto("/signout")
await page.waitForLoadState("domcontentloaded") await page.locator("button#signout").click()
await page.click("button#signout")
await page.waitForSelector("#start") await page.waitForSelector("#start")

View file

@ -9,7 +9,6 @@ import { and, desc, eq } from "drizzle-orm"
import db from "~/drizzle" import db from "~/drizzle"
import { verificationTokens } from "~/drizzle/schemas/Tables" import { verificationTokens } from "~/drizzle/schemas/Tables"
const callbackUrl = process.env.AUTH_URL as string
const player1Email = (browser: Browser) => const player1Email = (browser: Browser) =>
browser.browserType().name() + "-player-1@example.com" browser.browserType().name() + "-player-1@example.com"
@ -27,20 +26,13 @@ test.describe.serial("Check Email auth", () => {
}) })
test("Email login process...", async ({ browser }) => { test("Email login process...", async ({ browser }) => {
await page.goto(callbackUrl + "/signin") await page.goto("/signin")
await page.waitForSelector("input#email") await page.locator("input#email").fill(player1Email(browser))
await page.fill("input#email", player1Email(browser)) await page.locator("button#email-submit").click()
await page.click("button#email-submit")
await page.waitForURL( await page.waitForURL("/api/auth/verify-request?provider=email&type=email")
callbackUrl + "/api/auth/verify-request?provider=email&type=email",
)
await page.waitForLoadState("domcontentloaded")
})
test("Verify Email...", async ({ browser }) => {
const token = randomBytes(32).toString("hex") const token = randomBytes(32).toString("hex")
const hash = createHash("sha256") const hash = createHash("sha256")
@ -64,14 +56,21 @@ test.describe.serial("Check Email auth", () => {
) )
const params = new URLSearchParams({ const params = new URLSearchParams({
callbackUrl, callbackUrl: process.env.AUTH_URL!,
token, token,
email: player1Email(browser), email: player1Email(browser),
}) })
const url = callbackUrl + "/api/auth/callback/email?" + params
await page.goto(url) await page.goto("/api/auth/callback/email?" + params)
})
await page.waitForLoadState("domcontentloaded") test("Verify Logged in...", async () => {
await page.goto("/signin")
await page.waitForSelector("button#signout")
})
test("Logging out...", async () => {
await page.locator("button#signout").click()
await page.waitForSelector("#start")
}) })
}) })

View file

@ -1,6 +0,0 @@
/** @type {import('jest-environment-puppeteer').JestPuppeteerConfig} */
module.exports = {
launch: {
headless: "new",
},
}

View file

@ -41,6 +41,7 @@
"unique-names-generator": "^4.7.1", "unique-names-generator": "^4.7.1",
"zod": "3.21.1" "zod": "3.21.1"
}, },
"packageManager": "pnpm@8.7.4",
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.37.0", "@playwright/test": "^1.37.0",
"@total-typescript/ts-reset": "^0.4.2", "@total-typescript/ts-reset": "^0.4.2",

View file

@ -25,7 +25,7 @@ export default defineConfig({
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: { use: {
/* Base URL to use in actions like `await page.goto('/')`. */ /* Base URL to use in actions like `await page.goto('/')`. */
// baseURL: 'http://127.0.0.1:3000', baseURL: process.env.AUTH_URL!,
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: "on-first-retry", trace: "on-first-retry",

File diff suppressed because it is too large Load diff

View file

@ -1,17 +1,17 @@
import { Session } from "@auth/core/types" import { Session } from "@auth/core/types"
import { getSession } from "@auth/solid-start" import objectHash from "object-hash"
import { import {
JSX, JSX,
createContext, createContext,
createEffect, createEffect,
createResource,
createSignal, createSignal,
useContext, useContext,
} from "solid-js" } from "solid-js"
import { createServerData$ } from "solid-start/server" import { useIsRouting } from "solid-start"
import { authOptions } from "~/server/auth"
import { gameState, setMenu, setMode, users } from "./useGameProps" import { gameState, setMenu, setMode, users } from "./useGameProps"
const [state, setState] = createSignal<Session | null>(null) const [state, setState] = createSignal<Session | null | undefined>(undefined)
const selfIndex = () => { const selfIndex = () => {
switch (state()?.user?.id) { switch (state()?.user?.id) {
case users[0].id(): case users[0].id():
@ -61,13 +61,25 @@ const contextValue = {
export const SessionCtx = createContext(contextValue) export const SessionCtx = createContext(contextValue)
export function SessionProvider(props: { children: JSX.Element }) { export function SessionProvider(props: { children: JSX.Element }) {
const session = createServerData$( const fetchData = () =>
async (_, { request }) => { fetch("/api/session").then((res) =>
return await getSession(request, authOptions) res.ok ? (res.json() as Promise<Session>) : null,
}, )
{ key: () => ["auth_user"] }, const [data, { refetch }] = createResource(fetchData)
)() const isRouting = useIsRouting()
setState(session ?? null)
createEffect(() => {
if (!isRouting()) return
refetch()
})
createEffect(() => {
const session = data()
const hashDiff = objectHash(session ?? null) !== objectHash(state() ?? null)
if (session === undefined || data.loading || !hashDiff) return
console.log("Session updated.")
setState(session)
})
createEffect(() => { createEffect(() => {
if (gameState() !== "running") return if (gameState() !== "running") return

View file

@ -1,10 +1,10 @@
import { getSession } from "@auth/solid-start" import { getSession } from "@auth/solid-start"
import status from "http-status" import status from "http-status"
import { APIEvent, redirect } from "solid-start" import { APIEvent, json } from "solid-start"
import { authOptions } from "~/server/auth" import { authOptions } from "~/server/auth"
export async function GET({ request }: APIEvent) { export async function GET({ request }: APIEvent) {
const session = await getSession(request, authOptions) const session = await getSession(request, authOptions)
if (session) return redirect("/") if (session) return json(session)
else return new Response(null, { status: status["UNAUTHORIZED"] }) else return new Response(null, { status: status["UNAUTHORIZED"] })
} }

View file

@ -18,7 +18,7 @@ export default function Lobby() {
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.ico" />
<link <link
rel="preload" rel="preload"
href="/fonts/cpfont_ote/CP Font.otf" href="/fonts/cpfont_ote/CP_Font.otf"
as="font" as="font"
type="font/woff2" type="font/woff2"
/> />

View file

@ -10,7 +10,7 @@ function Logout() {
const navigator = useNavigate() const navigator = useNavigate()
createEffect(() => { createEffect(() => {
if (!session()) navigator("/signin") if (session() === null) navigator("/signin")
}) })
return ( return (

View file

@ -5,7 +5,7 @@
@import url("https://fonts.googleapis.com/css2?family=Farro:wght@300;400;500;700&display=swap"); @import url("https://fonts.googleapis.com/css2?family=Farro:wght@300;400;500;700&display=swap");
@font-face { @font-face {
font-family: "CP_Font"; font-family: "CP_Font";
src: url("/fonts/cpfont_ote/CP Font.otf") format("opentype"); src: url("/fonts/cpfont_ote/CP_Font.otf") format("opentype");
font-display: swap; font-display: swap;
} }

View file

@ -2,7 +2,7 @@ import solid from "solid-start/vite"
import { defineConfig } from "vite" import { defineConfig } from "vite"
export default defineConfig({ export default defineConfig({
plugins: [solid()], plugins: [solid({ ssr: false })],
server: { server: {
host: "0.0.0.0", host: "0.0.0.0",
strictPort: true, strictPort: true,