Working tests in ESM mode.
Summary: scss Reviewers: #reviewers, kuba-orlik Reviewed By: #reviewers, kuba-orlik Subscribers: jenkins-user Differential Revision: https://hub.sealcode.org/D1358
This commit is contained in:
parent
46e70efcb3
commit
f7538a362d
2
docker-up.sh
Executable file
2
docker-up.sh
Executable file
@ -0,0 +1,2 @@
|
||||
mkdir -p docker_node_modules
|
||||
docker-compose up -d
|
@ -1,9 +0,0 @@
|
||||
import { LONG_TEST_TIMEOUT } from "./src/back/test_utils/webhint";
|
||||
import { closeBrowser } from "./src/back/test_utils/browser-creator";
|
||||
|
||||
exports.mochaHooks = {
|
||||
async afterAll() {
|
||||
this.timeout(LONG_TEST_TIMEOUT);
|
||||
await closeBrowser();
|
||||
},
|
||||
};
|
2
npm.sh
2
npm.sh
@ -2,6 +2,8 @@
|
||||
|
||||
# the "--no-TTY" option is crucial - without it the output is not captured in Jenkins
|
||||
|
||||
./docker-up.sh
|
||||
|
||||
CONTAINER_ID=$(docker-compose run \
|
||||
-d \
|
||||
--service-ports \
|
||||
|
5461
package-lock.json
generated
5461
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
43
package.json
43
package.json
@ -12,10 +12,12 @@
|
||||
"watch": "multiple-scripts-tmux -p watch",
|
||||
"reset-db": "docker-compose down && docker-compose up -d",
|
||||
"install-test-deps": "npx playwright install firefox",
|
||||
"test": "npm run install-test-deps && TS_NODE_PROJECT='./src/back/tsconfig.json' mocha --recursive --timeout 20000 --require ts-node/register --require mocha_root_hooks.js src/back/app.ts src/back/**/*.test.ts src/back/**/**/*.test.ts src/back/**/**/**/*.test.ts src/back/**/**/**/**/*.test.ts",
|
||||
"coverage": "nyc npm run test --",
|
||||
"test-cmd": "vitest --config ./src/back/vitest.config.ts",
|
||||
"test-cmd-once": "vitest run --config ./src/back/vitest.config.ts",
|
||||
"test": "npm run test-cmd -- --ui",
|
||||
"coverage": "npm run test --coverage",
|
||||
"postinstall": "sealgen make-env",
|
||||
"test-reports": "docker-compose up -d && ./npm.sh run coverage -- --reporter xunit --reporter-option output=.xunit",
|
||||
"test-reports": "npm run test-cmd-once -- --coverage",
|
||||
"show-coverage": "npm run test-reports; xdg-open coverage/index.html"
|
||||
},
|
||||
"tmux-scripts": {
|
||||
@ -36,60 +38,43 @@
|
||||
"@sealcode/sealgen": "^0.9.0",
|
||||
"@sealcode/ts-predicates": "^0.4.3",
|
||||
"@types/kill-port": "^2.0.0",
|
||||
"get-port": "^7.0.0",
|
||||
"hint": "^7.0.1",
|
||||
"locreq": "^2.0.2",
|
||||
"locreq": "^3.0.0",
|
||||
"multiple-scripts-tmux": "^1.0.4",
|
||||
"nodemon": "^3.0.1",
|
||||
"sealious": "^0.17.37",
|
||||
"stimulus": "^2.0.0",
|
||||
"tempstream": "^0.0.21"
|
||||
"tempstream": "^0.0.21",
|
||||
"vitest": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@hint/connector-jsdom": "^4.1.20",
|
||||
"@hint/formatter-codeframe": "^3.1.29",
|
||||
"@hint/hint-doctype": "^3.3.19",
|
||||
"@hint/hint-no-broken-links": "^4.2.19",
|
||||
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
||||
"@sealcode/ansi-html-stream": "^1.0.1",
|
||||
"@types/koa__router": "^12.0.4",
|
||||
"@types/mocha": "^9.1.1",
|
||||
"@types/node": "^20.8.4",
|
||||
"@types/tedious": "^4.0.7",
|
||||
"@typescript-eslint/eslint-plugin": "^5.10.0",
|
||||
"@typescript-eslint/parser": "^5.10.2",
|
||||
"axios": "^0.24.0",
|
||||
"@vitest/coverage-istanbul": "^1.1.0",
|
||||
"@vitest/coverage-v8": "^1.1.0",
|
||||
"@vitest/ui": "^1.1.0",
|
||||
"axios": "^1.6.2",
|
||||
"eslint": "^7.19.0",
|
||||
"eslint-config-prettier": "^7.2.0",
|
||||
"eslint-plugin-prettier": "^3.3.1",
|
||||
"eslint-plugin-with-tsc-error": "^0.0.7",
|
||||
"kill-port": "^1.6.1",
|
||||
"mocha": "^8.4.0",
|
||||
"mri": "^1.1.6",
|
||||
"nyc": "^15.1.0",
|
||||
"prettier": "^2.2.1",
|
||||
"ts-loader": "^8.0.14",
|
||||
"ts-node": "^10.4.0",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^4.7"
|
||||
},
|
||||
"nyc": {
|
||||
"extends": "@istanbuljs/nyc-config-typescript",
|
||||
"check-coverage": false,
|
||||
"all": true,
|
||||
"include": [
|
||||
"src/**/!(*.test.*).[tj]s?(x)"
|
||||
],
|
||||
"exclude": [
|
||||
"src/_tests_/**/*.*"
|
||||
],
|
||||
"reporter": [
|
||||
"html",
|
||||
"lcov",
|
||||
"clover",
|
||||
"text",
|
||||
"text-summary"
|
||||
],
|
||||
"report-dir": "coverage"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=17.0.0"
|
||||
}
|
||||
|
@ -4,14 +4,22 @@ import type { LoggerLevel } from "sealious/@types/src/app/logger.js";
|
||||
import { collections } from "./collections/collections.js";
|
||||
import ADMIN_CREDENTIALS from "./default-admin-credentials.js";
|
||||
import { module_dirname } from "./util.js";
|
||||
const locreq = _locreq.default(module_dirname(import.meta.url));
|
||||
const locreq = _locreq(module_dirname(import.meta.url));
|
||||
|
||||
const PORT = process.env.SEALIOUS_PORT ? parseInt(process.env.SEALIOUS_PORT) : 8080;
|
||||
const base_url = process.env.SEALIOUS_BASE_URL || `http://localhost:${PORT}`;
|
||||
const MONGO_PORT = process.env.SEALIOUS_MONGO_PORT
|
||||
export const MONGO_PORT = process.env.SEALIOUS_MONGO_PORT
|
||||
? parseInt(process.env.SEALIOUS_MONGO_PORT)
|
||||
: 20747;
|
||||
const MONGO_HOST = process.env.SEALIOUS_MONGO_HOST || "127.0.0.1";
|
||||
export const MONGO_HOST = process.env.SEALIOUS_MONGO_HOST || "127.0.0.1";
|
||||
export const MAILCATCHER_HOST = process.env.SEALIOUS_MAILCATCHER_HOST || "127.0.0.1";
|
||||
export const MAILCATCHER_SMTP_PORT = parseInt(
|
||||
process.env.SEALIOUS_MAILCATCHER_SMTP_PORT || "1026"
|
||||
);
|
||||
export const MAILCATCHER_API_PORT = parseInt(
|
||||
process.env.SEALIOUS_MAILCATCHER_API_PORT || "1082"
|
||||
);
|
||||
export const MAILER = process.env.SEALIOUS_MAILER;
|
||||
|
||||
declare module "koa" {
|
||||
interface BaseContext {
|
||||
@ -56,10 +64,10 @@ export default class TheApp extends App {
|
||||
};
|
||||
collections = collections;
|
||||
mailer =
|
||||
process.env.SEALIOUS_MAILER === "mailcatcher"
|
||||
MAILER === "mailcatcher"
|
||||
? new SMTPMailer({
|
||||
host: "mailcatcher",
|
||||
port: 1025,
|
||||
host: MAILCATCHER_HOST,
|
||||
port: MAILCATCHER_SMTP_PORT,
|
||||
user: "any",
|
||||
password: "any",
|
||||
})
|
||||
|
@ -2,6 +2,7 @@ import axios from "axios";
|
||||
import assert from "assert";
|
||||
import TheApp from "../app.js";
|
||||
import { withProdApp } from "../test_utils/with-prod-app.js";
|
||||
import { LONG_TEST_TIMEOUT } from "../test_utils/webhint.js";
|
||||
|
||||
describe("password-reset-intents", function () {
|
||||
//ts-ignore
|
||||
@ -14,11 +15,13 @@ describe("password-reset-intents", function () {
|
||||
});
|
||||
}
|
||||
|
||||
it("tells you if the email address doesn't exist", async function () {
|
||||
it(
|
||||
"tells you if the email address doesn't exist",
|
||||
async function () {
|
||||
return withProdApp(async ({ app, base_url }) => {
|
||||
const email = "fake@example.com";
|
||||
try {
|
||||
await axios.default.post(
|
||||
await axios.post(
|
||||
`${base_url}/api/v1/collections/password-reset-intents`,
|
||||
{
|
||||
email: email,
|
||||
@ -33,13 +36,17 @@ describe("password-reset-intents", function () {
|
||||
}
|
||||
throw new Error("it didn't throw");
|
||||
});
|
||||
});
|
||||
},
|
||||
LONG_TEST_TIMEOUT
|
||||
);
|
||||
|
||||
it("allows anyone to create an intent, if the email exists", async () =>
|
||||
it(
|
||||
"allows anyone to create an intent, if the email exists",
|
||||
async () =>
|
||||
withProdApp(async ({ app, base_url }) => {
|
||||
await createAUser(app);
|
||||
const { email, token } = (
|
||||
await axios.default.post(
|
||||
await axios.post(
|
||||
`${base_url}/api/v1/collections/password-reset-intents`,
|
||||
{
|
||||
email: "user@example.com",
|
||||
@ -53,13 +60,15 @@ describe("password-reset-intents", function () {
|
||||
token: "it's a secret to everybody",
|
||||
}
|
||||
);
|
||||
}));
|
||||
}),
|
||||
LONG_TEST_TIMEOUT
|
||||
);
|
||||
|
||||
it("tells you if the email address is malformed", async () =>
|
||||
withProdApp(async ({ app, base_url }) => {
|
||||
const email = "incorrect-address";
|
||||
try {
|
||||
await axios.default.post(
|
||||
await axios.post(
|
||||
`${base_url}/api/v1/collections/password-reset-intents`,
|
||||
{
|
||||
email: email,
|
||||
@ -78,12 +87,9 @@ describe("password-reset-intents", function () {
|
||||
it("sends an email with the reset password link", async () =>
|
||||
withProdApp(async ({ app, base_url, mail_api }) => {
|
||||
await createAUser(app);
|
||||
await axios.default.post(
|
||||
`${base_url}/api/v1/collections/password-reset-intents`,
|
||||
{
|
||||
await axios.post(`${base_url}/api/v1/collections/password-reset-intents`, {
|
||||
email: "user@example.com",
|
||||
}
|
||||
);
|
||||
});
|
||||
const messages = (await mail_api.getMessages()).filter(
|
||||
(message) => message.recipients[0] == "<user@example.com>"
|
||||
);
|
||||
|
@ -4,9 +4,12 @@ import { Context, TestUtils } from "sealious";
|
||||
import { withProdApp } from "../test_utils/with-prod-app.js";
|
||||
import { createAdmin, createAUser } from "../test_utils/users.js";
|
||||
import Users from "./users.js";
|
||||
import { LONG_TEST_TIMEOUT } from "../test_utils/webhint.js";
|
||||
|
||||
describe("user-roles", () => {
|
||||
it("rejects when given an empty role", async () =>
|
||||
it(
|
||||
"rejects when given an empty role",
|
||||
async () =>
|
||||
withProdApp(async ({ app, rest_api }) => {
|
||||
const [user, session] = await createAdmin(app, rest_api);
|
||||
await TestUtils.assertThrowsAsync(
|
||||
@ -26,12 +29,14 @@ describe("user-roles", () => {
|
||||
);
|
||||
}
|
||||
);
|
||||
}));
|
||||
}),
|
||||
LONG_TEST_TIMEOUT
|
||||
);
|
||||
|
||||
it("accepts correct dataset", async () =>
|
||||
withProdApp(async ({ app, base_url, rest_api }) => {
|
||||
const [user, session] = await createAdmin(app, rest_api);
|
||||
const response = await axios.default.post(
|
||||
const response = await axios.post(
|
||||
`${base_url}/api/v1/collections/user-roles`,
|
||||
{
|
||||
user: user.id,
|
||||
|
@ -3,7 +3,7 @@ import _locreq from "locreq";
|
||||
import TheApp from "./app.js";
|
||||
import { mainRouter } from "./routes/index.js";
|
||||
import { module_dirname } from "./util.js";
|
||||
const locreq = _locreq.default(module_dirname(import.meta.url));
|
||||
const locreq = _locreq(module_dirname(import.meta.url));
|
||||
|
||||
const app = new TheApp();
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Context } from "koa";
|
||||
import { tempstream } from "tempstream";
|
||||
import { Page } from "@sealcode/sealgen";
|
||||
import html from "../html";
|
||||
import html from "../html.js";
|
||||
|
||||
export const actionName = "Hello";
|
||||
|
||||
|
@ -3,8 +3,9 @@ import { withProdApp } from "../test_utils/with-prod-app.js";
|
||||
import { HelloURL } from "./urls.js";
|
||||
|
||||
describe("Hello", () => {
|
||||
it("doesn't crash", async function () {
|
||||
this.timeout(VERY_LONG_TEST_TIMEOUT);
|
||||
it(
|
||||
"doesn't crash",
|
||||
async function () {
|
||||
return withProdApp(async ({ base_url, rest_api }) => {
|
||||
await rest_api.get(HelloURL);
|
||||
await webhintURL(base_url + HelloURL);
|
||||
@ -13,5 +14,7 @@ describe("Hello", () => {
|
||||
// const response = await rest_api.get(HelloURL);
|
||||
// await webhintHTML(response);
|
||||
});
|
||||
});
|
||||
},
|
||||
VERY_LONG_TEST_TIMEOUT
|
||||
);
|
||||
});
|
||||
|
@ -2,9 +2,12 @@ import { VERY_LONG_TEST_TIMEOUT, webhintURL } from "../test_utils/webhint.js";
|
||||
import { withProdApp } from "../test_utils/with-prod-app.js";
|
||||
|
||||
describe("homepage", function () {
|
||||
this.timeout(VERY_LONG_TEST_TIMEOUT);
|
||||
it("passes webhint tests", () =>
|
||||
it(
|
||||
"passes webhint tests",
|
||||
() =>
|
||||
withProdApp(async ({ base_url }) => {
|
||||
await webhintURL(`${base_url}/`);
|
||||
}));
|
||||
}),
|
||||
VERY_LONG_TEST_TIMEOUT
|
||||
);
|
||||
});
|
||||
|
@ -6,7 +6,7 @@ import { LONG_TEST_TIMEOUT, VERY_LONG_TEST_TIMEOUT } from "../test_utils/webhint
|
||||
import { withProdApp } from "../test_utils/with-prod-app.js";
|
||||
import { LogoutURL, SignInURL } from "./urls.js";
|
||||
|
||||
describe("Logout", () => {
|
||||
describe.concurrent("Logout", () => {
|
||||
let page: Page;
|
||||
let browser: Browser;
|
||||
let context: BrowserContext;
|
||||
@ -23,8 +23,9 @@ describe("Logout", () => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it("doesn't crash", async function () {
|
||||
this.timeout(VERY_LONG_TEST_TIMEOUT);
|
||||
it(
|
||||
"doesn't crash",
|
||||
async function () {
|
||||
return withProdApp(async ({ rest_api }) => {
|
||||
await assert.rejects(
|
||||
async () => {
|
||||
@ -33,12 +34,15 @@ describe("Logout", () => {
|
||||
{ name: "Error" }
|
||||
);
|
||||
});
|
||||
});
|
||||
},
|
||||
VERY_LONG_TEST_TIMEOUT
|
||||
);
|
||||
|
||||
describe("logout test", () => {
|
||||
it("logout", async function () {
|
||||
it(
|
||||
"logout",
|
||||
async function () {
|
||||
await withProdApp(async ({ base_url }) => {
|
||||
this.timeout(LONG_TEST_TIMEOUT);
|
||||
await page.goto(base_url);
|
||||
await page.getByRole("link", { name: "Sign in" }).click();
|
||||
await page.getByPlaceholder("text").click();
|
||||
@ -50,6 +54,8 @@ describe("Logout", () => {
|
||||
await page.getByRole("link", { name: "Logout" }).click();
|
||||
await page.waitForSelector(`a[href="${SignInURL}"]`);
|
||||
});
|
||||
});
|
||||
},
|
||||
LONG_TEST_TIMEOUT
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -1,29 +1,17 @@
|
||||
import { Browser, BrowserContext, Page } from "@playwright/test";
|
||||
import ADMIN_CREDENTIALS from "../default-admin-credentials.js";
|
||||
import { getBrowser } from "../test_utils/browser-creator.js";
|
||||
import { getBrowser, getPage } from "../test_utils/browser-creator.js";
|
||||
import { VERY_LONG_TEST_TIMEOUT, webhintURL } from "../test_utils/webhint.js";
|
||||
import { withProdApp } from "../test_utils/with-prod-app.js";
|
||||
import { LogoutURL, SignInURL } from "./urls.js";
|
||||
|
||||
describe("SignIn", () => {
|
||||
let page: Page;
|
||||
let browser: Browser;
|
||||
let context: BrowserContext;
|
||||
const username = ADMIN_CREDENTIALS.username;
|
||||
const password = ADMIN_CREDENTIALS.password;
|
||||
|
||||
beforeEach(async () => {
|
||||
browser = await getBrowser();
|
||||
context = await browser.newContext();
|
||||
page = await context.newPage();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it("doesn't crash", async function () {
|
||||
this.timeout(VERY_LONG_TEST_TIMEOUT);
|
||||
it(
|
||||
"doesn't crash",
|
||||
async function () {
|
||||
return withProdApp(async ({ base_url, rest_api }) => {
|
||||
await rest_api.get(SignInURL);
|
||||
await webhintURL(base_url + SignInURL);
|
||||
@ -32,12 +20,16 @@ describe("SignIn", () => {
|
||||
// const response = await rest_api.get(SignInURL);
|
||||
// await webhintHTML(response);
|
||||
});
|
||||
});
|
||||
},
|
||||
VERY_LONG_TEST_TIMEOUT
|
||||
);
|
||||
|
||||
describe("can access test", () => {
|
||||
it("access url", async function () {
|
||||
it(
|
||||
"access url",
|
||||
async function () {
|
||||
await withProdApp(async ({ base_url }) => {
|
||||
this.timeout(VERY_LONG_TEST_TIMEOUT);
|
||||
const { context, page } = await getPage();
|
||||
await page.goto(base_url);
|
||||
await page.getByRole("link", { name: "Sign in" }).click();
|
||||
await page.getByPlaceholder("text").click();
|
||||
@ -51,14 +43,19 @@ describe("SignIn", () => {
|
||||
await page.goto(base_url);
|
||||
await page.getByRole("link", { name: "Logout" }).click();
|
||||
await page.waitForSelector(`a[href="${SignInURL}"]`);
|
||||
await context.close();
|
||||
});
|
||||
});
|
||||
},
|
||||
VERY_LONG_TEST_TIMEOUT
|
||||
);
|
||||
});
|
||||
|
||||
describe("sign in test", () => {
|
||||
it("wrong username", async function () {
|
||||
it(
|
||||
"wrong username",
|
||||
async function () {
|
||||
await withProdApp(async ({ base_url }) => {
|
||||
this.timeout(VERY_LONG_TEST_TIMEOUT);
|
||||
const { context, page } = await getPage();
|
||||
await page.goto(base_url);
|
||||
await page.getByRole("link", { name: "Sign in" }).click();
|
||||
await page.getByPlaceholder("text").click();
|
||||
@ -67,12 +64,17 @@ describe("SignIn", () => {
|
||||
await page.getByPlaceholder("password").fill("test");
|
||||
await page.getByPlaceholder("password").press("Enter");
|
||||
await page.waitForSelector(".form-message");
|
||||
await context.close();
|
||||
});
|
||||
});
|
||||
},
|
||||
VERY_LONG_TEST_TIMEOUT
|
||||
);
|
||||
|
||||
it("correct username and password", async function () {
|
||||
it(
|
||||
"correct username and password",
|
||||
async function () {
|
||||
await withProdApp(async ({ base_url }) => {
|
||||
this.timeout(VERY_LONG_TEST_TIMEOUT);
|
||||
const { context, page } = await getPage();
|
||||
await page.goto(base_url);
|
||||
await page.getByRole("link", { name: "Sign in" }).click();
|
||||
await page.getByPlaceholder("text").click();
|
||||
@ -83,12 +85,17 @@ describe("SignIn", () => {
|
||||
await page.waitForSelector(`a[href="${LogoutURL}"]`);
|
||||
await page.getByRole("link", { name: "Logout" }).click();
|
||||
await page.waitForSelector(`a[href="${SignInURL}"]`);
|
||||
await context.close();
|
||||
});
|
||||
});
|
||||
},
|
||||
VERY_LONG_TEST_TIMEOUT
|
||||
);
|
||||
|
||||
it("wrong password", async function () {
|
||||
it(
|
||||
"wrong password",
|
||||
async function () {
|
||||
await withProdApp(async ({ base_url }) => {
|
||||
this.timeout(VERY_LONG_TEST_TIMEOUT);
|
||||
const { context, page } = await getPage();
|
||||
await page.goto(base_url);
|
||||
await page.getByRole("link", { name: "Sign in" }).click();
|
||||
await page.getByPlaceholder("text").click();
|
||||
@ -97,7 +104,10 @@ describe("SignIn", () => {
|
||||
await page.getByPlaceholder("password").fill("asddasads20230720722");
|
||||
await page.getByPlaceholder("password").press("Enter");
|
||||
await page.waitForSelector(".form-message");
|
||||
await context.close();
|
||||
});
|
||||
});
|
||||
},
|
||||
VERY_LONG_TEST_TIMEOUT
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -5,6 +5,19 @@ import { VERY_LONG_TEST_TIMEOUT, webhintURL } from "../test_utils/webhint.js";
|
||||
import { withProdApp } from "../test_utils/with-prod-app.js";
|
||||
import { LogoutURL, SignInURL, SignUpURL } from "./urls.js";
|
||||
|
||||
describe("SignUp webhint", () => {
|
||||
it(
|
||||
"doesn't crash",
|
||||
async function () {
|
||||
return withProdApp(async ({ base_url, rest_api }) => {
|
||||
await rest_api.get(SignUpURL);
|
||||
await webhintURL(base_url + SignUpURL);
|
||||
});
|
||||
},
|
||||
VERY_LONG_TEST_TIMEOUT
|
||||
);
|
||||
});
|
||||
|
||||
describe("SignUp", () => {
|
||||
let page: Page;
|
||||
let browser: Browser;
|
||||
@ -23,37 +36,32 @@ describe("SignUp", () => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it("doesn't crash", async function () {
|
||||
this.timeout(VERY_LONG_TEST_TIMEOUT);
|
||||
return withProdApp(async ({ base_url, rest_api }) => {
|
||||
await rest_api.get(SignUpURL);
|
||||
await webhintURL(base_url + SignUpURL);
|
||||
// alternatively you can use webhintHTML for faster but less precise scans
|
||||
// or for scanning responses of requests that use some form of authorization:
|
||||
// const response = await rest_api.get(SignUpURL);
|
||||
// await webhintHTML(response);
|
||||
});
|
||||
});
|
||||
|
||||
describe("signup test", () => {
|
||||
it("username is taken", async function () {
|
||||
it(
|
||||
"username is taken",
|
||||
async function () {
|
||||
await withProdApp(async ({ base_url }) => {
|
||||
this.timeout(VERY_LONG_TEST_TIMEOUT);
|
||||
await page.goto(base_url);
|
||||
await page.getByRole("link", { name: "Sign up" }).click();
|
||||
await page.getByPlaceholder("text").click();
|
||||
await page.getByPlaceholder("text").fill(username);
|
||||
await page.getByPlaceholder("text").press("Tab");
|
||||
await page.getByPlaceholder("email").fill("user0192939@randomsuper.com");
|
||||
await page
|
||||
.getByPlaceholder("email")
|
||||
.fill("user0192939@randomsuper.com");
|
||||
await page.getByPlaceholder("email").press("Tab");
|
||||
await page.getByPlaceholder("password").fill("user12341234");
|
||||
await page.getByRole("button", { name: "Wyślij" }).click();
|
||||
await page.waitForSelector(".input__error");
|
||||
});
|
||||
});
|
||||
it("password is too shot ", async function () {
|
||||
},
|
||||
VERY_LONG_TEST_TIMEOUT
|
||||
);
|
||||
|
||||
it(
|
||||
"password is too shot ",
|
||||
async function () {
|
||||
await withProdApp(async ({ base_url }) => {
|
||||
this.timeout(VERY_LONG_TEST_TIMEOUT);
|
||||
await page.goto(base_url);
|
||||
await page.getByRole("link", { name: "Sign up" }).click();
|
||||
await page.getByPlaceholder("text").click();
|
||||
@ -67,10 +75,14 @@ describe("SignUp", () => {
|
||||
await page.getByRole("button", { name: "Wyślij" }).click();
|
||||
await page.waitForSelector(".form-message.form-message--error");
|
||||
});
|
||||
});
|
||||
it("email is taken", async function () {
|
||||
},
|
||||
VERY_LONG_TEST_TIMEOUT
|
||||
);
|
||||
|
||||
it(
|
||||
"email is taken",
|
||||
async function () {
|
||||
await withProdApp(async ({ base_url }) => {
|
||||
this.timeout(VERY_LONG_TEST_TIMEOUT);
|
||||
await page.goto(base_url);
|
||||
await page.getByRole("link", { name: "Sign up" }).click();
|
||||
await page.getByPlaceholder("text").click();
|
||||
@ -82,27 +94,36 @@ describe("SignUp", () => {
|
||||
await page.getByRole("button", { name: "Wyślij" }).click();
|
||||
await page.waitForSelector(".form-message.form-message--error");
|
||||
});
|
||||
});
|
||||
it("correct", async function () {
|
||||
},
|
||||
VERY_LONG_TEST_TIMEOUT
|
||||
);
|
||||
|
||||
it(
|
||||
"correct",
|
||||
async function () {
|
||||
await withProdApp(async ({ base_url }) => {
|
||||
this.timeout(VERY_LONG_TEST_TIMEOUT);
|
||||
await page.goto(base_url);
|
||||
await page.getByRole("link", { name: "Sign up" }).click();
|
||||
await page.getByPlaceholder("text").click();
|
||||
await page.getByPlaceholder("text").fill("ranomusername20230720722");
|
||||
await page.getByPlaceholder("text").press("Tab");
|
||||
await page.getByPlaceholder("email").fill("radomemail@emailrandom.com");
|
||||
await page
|
||||
.getByPlaceholder("email")
|
||||
.fill("radomemail@emailrandom.com");
|
||||
await page.getByPlaceholder("email").press("Tab");
|
||||
await page.getByPlaceholder("password").fill("asdasdasdasdasd");
|
||||
await page.getByRole("button", { name: "Wyślij" }).click();
|
||||
await page.waitForSelector(".success-notify");
|
||||
});
|
||||
});
|
||||
},
|
||||
VERY_LONG_TEST_TIMEOUT
|
||||
);
|
||||
});
|
||||
describe("can access test", () => {
|
||||
it("access url", async function () {
|
||||
it(
|
||||
"access url",
|
||||
async function () {
|
||||
await withProdApp(async ({ base_url }) => {
|
||||
this.timeout(VERY_LONG_TEST_TIMEOUT);
|
||||
await page.goto(base_url);
|
||||
await page.getByRole("link", { name: "Sign in" }).click();
|
||||
await page.getByPlaceholder("text").click();
|
||||
@ -117,6 +138,8 @@ describe("SignUp", () => {
|
||||
await page.getByRole("link", { name: "Logout" }).click();
|
||||
await page.waitForSelector(`a[href="${SignInURL}"]`);
|
||||
});
|
||||
});
|
||||
},
|
||||
VERY_LONG_TEST_TIMEOUT
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -6,6 +6,23 @@ import { LONG_TEST_TIMEOUT, VERY_LONG_TEST_TIMEOUT } from "../test_utils/webhint
|
||||
import { withProdApp } from "../test_utils/with-prod-app.js";
|
||||
import { SignInURL, TodoURL } from "./urls.js";
|
||||
|
||||
describe("Todo webhint", () => {
|
||||
it(
|
||||
"doesn't crash",
|
||||
async function () {
|
||||
return withProdApp(async ({ rest_api }) => {
|
||||
await assert.rejects(
|
||||
async () => {
|
||||
await rest_api.get(TodoURL);
|
||||
},
|
||||
{ name: "Error" }
|
||||
);
|
||||
});
|
||||
},
|
||||
VERY_LONG_TEST_TIMEOUT
|
||||
);
|
||||
});
|
||||
|
||||
describe("Todo", function () {
|
||||
let page: Page;
|
||||
let browser: Browser;
|
||||
@ -23,22 +40,11 @@ describe("Todo", function () {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it("doesn't crash", async function () {
|
||||
this.timeout(VERY_LONG_TEST_TIMEOUT);
|
||||
return withProdApp(async ({ rest_api }) => {
|
||||
await assert.rejects(
|
||||
async () => {
|
||||
await rest_api.get(TodoURL);
|
||||
},
|
||||
{ name: "Error" }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("todo test", () => {
|
||||
it("create and delete task", async function () {
|
||||
it(
|
||||
"create and delete task",
|
||||
async function () {
|
||||
await withProdApp(async ({ base_url }) => {
|
||||
this.timeout(VERY_LONG_TEST_TIMEOUT);
|
||||
await page.goto(base_url);
|
||||
await page.getByRole("link", { name: "Sign in" }).click();
|
||||
await page.getByPlaceholder("text").click();
|
||||
@ -48,7 +54,9 @@ describe("Todo", function () {
|
||||
await page.getByPlaceholder("password").press("Enter");
|
||||
await page.getByRole("link", { name: "To do app" }).click();
|
||||
await page.getByPlaceholder("Write an Matrix bot").click();
|
||||
await page.getByPlaceholder("Write an Matrix bot").fill("randomtasdk");
|
||||
await page
|
||||
.getByPlaceholder("Write an Matrix bot")
|
||||
.fill("randomtasdk");
|
||||
await page.getByRole("button", { name: "Wyślij" }).click();
|
||||
await page.waitForSelector(".form-message.form-message--success");
|
||||
await page.locator("turbo-frame").getByRole("checkbox").check();
|
||||
@ -60,13 +68,16 @@ describe("Todo", function () {
|
||||
await page.getByRole("link", { name: "Logout" }).click();
|
||||
await page.waitForSelector(`a[href="${SignInURL}"]`);
|
||||
});
|
||||
});
|
||||
},
|
||||
VERY_LONG_TEST_TIMEOUT
|
||||
);
|
||||
});
|
||||
|
||||
describe("can access test", () => {
|
||||
it("access url", async function () {
|
||||
it(
|
||||
"access url",
|
||||
async function () {
|
||||
await withProdApp(async ({ base_url }) => {
|
||||
this.timeout(LONG_TEST_TIMEOUT);
|
||||
await page.goto(base_url);
|
||||
try {
|
||||
await page.waitForSelector(`a[href="${SignInURL}"]`);
|
||||
@ -76,6 +87,8 @@ describe("Todo", function () {
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
LONG_TEST_TIMEOUT
|
||||
);
|
||||
});
|
||||
});
|
||||
|
5
src/back/test-teardown.ts
Normal file
5
src/back/test-teardown.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { closeBrowser } from "./test_utils/browser-creator.js";
|
||||
|
||||
afterAll(async () => {
|
||||
await closeBrowser();
|
||||
});
|
@ -1,4 +1,4 @@
|
||||
import { Browser, firefox } from "@playwright/test";
|
||||
import { Browser, BrowserContext, firefox, Page } from "@playwright/test";
|
||||
|
||||
let browser: Browser;
|
||||
|
||||
@ -14,3 +14,14 @@ export async function closeBrowser() {
|
||||
await browser.close();
|
||||
}
|
||||
}
|
||||
|
||||
export async function getPage(): Promise<{
|
||||
page: Page;
|
||||
browser: Browser;
|
||||
context: BrowserContext;
|
||||
}> {
|
||||
const browser = await getBrowser();
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
return { browser, context, page };
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import _locreq from "locreq";
|
||||
const locreq = _locreq.default(__dirname);
|
||||
const locreq = _locreq(__dirname);
|
||||
import { spawn } from "child_process";
|
||||
import { hasShape, is, predicates } from "@sealcode/ts-predicates";
|
||||
import { promises as fs } from "fs";
|
||||
|
@ -1,12 +1,21 @@
|
||||
import _locreq from "locreq";
|
||||
import { v4 as uuid } from "uuid";
|
||||
|
||||
const locreq = _locreq.default(module_dirname(import.meta.url));
|
||||
const locreq = _locreq(module_dirname(import.meta.url));
|
||||
import { SMTPMailer } from "sealious";
|
||||
import { TestUtils } from "sealious";
|
||||
import TheApp from "../app.js";
|
||||
import TheApp, {
|
||||
MAILCATCHER_API_PORT,
|
||||
MAILCATCHER_HOST,
|
||||
MAILCATCHER_SMTP_PORT,
|
||||
} from "../app.js";
|
||||
import { mainRouter } from "../routes/index.js";
|
||||
import { module_dirname } from "../util.js";
|
||||
import getPort from "get-port";
|
||||
|
||||
const port_numbers = async function* () {
|
||||
yield await getPort();
|
||||
};
|
||||
|
||||
export async function withProdApp(
|
||||
callback: (args: {
|
||||
@ -17,18 +26,17 @@ export async function withProdApp(
|
||||
}) => Promise<void>
|
||||
) {
|
||||
const app = new TheApp();
|
||||
const port = 9999;
|
||||
const port = (await port_numbers().next()).value as number;
|
||||
|
||||
app.config["www-server"].port = port;
|
||||
app.config.datastore_mongo = {
|
||||
host: "db",
|
||||
port: 27017,
|
||||
...app.config.datastore_mongo,
|
||||
db_name: "sealious-app-test" + uuid(),
|
||||
};
|
||||
app.config.logger.level = <const>"none";
|
||||
app.mailer = new SMTPMailer({
|
||||
host: "mailcatcher",
|
||||
port: 1025,
|
||||
host: "127.0.0.1",
|
||||
port: MAILCATCHER_SMTP_PORT,
|
||||
user: "any",
|
||||
password: "any",
|
||||
});
|
||||
@ -39,7 +47,10 @@ export async function withProdApp(
|
||||
|
||||
await app.start();
|
||||
const base_url = `http://127.0.0.1:${port}`;
|
||||
const mail_api = new TestUtils.MailcatcherAPI("http://mailcatcher:1080", app);
|
||||
const mail_api = new TestUtils.MailcatcherAPI(
|
||||
`http://${MAILCATCHER_HOST}:${MAILCATCHER_API_PORT}`,
|
||||
app
|
||||
);
|
||||
await mail_api.deleteAllInstanceEmails();
|
||||
|
||||
async function stop() {
|
||||
|
@ -14,7 +14,9 @@
|
||||
"allowJs": true,
|
||||
"resolveJsonModule": true,
|
||||
"sourceMap": true,
|
||||
"skipLibCheck": true
|
||||
"skipLibCheck": true,
|
||||
"types": ["vitest/globals"]
|
||||
},
|
||||
"include": ["./**/*", "./*"]
|
||||
"include": ["./**/*", "./*"],
|
||||
"ts-node": { "experimentalResolver": true, "esm": true }
|
||||
}
|
||||
|
16
src/back/vitest.config.ts
Normal file
16
src/back/vitest.config.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
testTimeout: 10000,
|
||||
setupFiles: ["src/back/test-teardown.ts"],
|
||||
exclude: ["docker_node_modules", "node_modules", "dist", "lib"],
|
||||
globals: true,
|
||||
coverage: {
|
||||
exclude: ["docker_node_modules", "node_modules", "dist", "lib"],
|
||||
enabled: true,
|
||||
all: true,
|
||||
include: ["src/**", "test?(-*).?(c|m)[jt]s?(x)"],
|
||||
},
|
||||
},
|
||||
});
|
@ -2,3 +2,4 @@
|
||||
|
||||
@import "../node_modules/@sealcode/sealgen/src/forms/forms.scss";
|
||||
@import "back/routes/common/ui/input.scss";
|
||||
@import "tables.scss";
|
||||
|
@ -1,37 +0,0 @@
|
||||
const path = require("path");
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
name: "front-end-components",
|
||||
entry: {
|
||||
bundle: "./src/front/index.ts",
|
||||
},
|
||||
|
||||
output: {
|
||||
filename: "[name].js",
|
||||
path: path.resolve(__dirname, "public/dist"),
|
||||
},
|
||||
|
||||
mode: "production",
|
||||
devtool: "source-map",
|
||||
|
||||
resolve: {
|
||||
extensions: [".ts", ".js"],
|
||||
},
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: [/node_modules/],
|
||||
use: [{ loader: "babel-loader" }],
|
||||
},
|
||||
{
|
||||
test: /\.ts$/,
|
||||
exclude: [/node_modules/],
|
||||
use: [{ loader: "ts-loader" }],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
Loading…
x
Reference in New Issue
Block a user