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
master
Kuba Orlik 4 months ago
parent 46e70efcb3
commit f7538a362d

@ -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,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 \

5709
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -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,52 +15,60 @@ describe("password-reset-intents", 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(
`${base_url}/api/v1/collections/password-reset-intents`,
{
email: email,
}
);
} catch (e) {
assert.equal(
e.response.data.data.field_messages.email.message,
app.i18n("invalid_existing_value", ["users", "email", email])
);
return;
}
throw new Error("it didn't throw");
});
});
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.post(
`${base_url}/api/v1/collections/password-reset-intents`,
{
email: email,
}
);
} catch (e) {
assert.equal(
e.response.data.data.field_messages.email.message,
app.i18n("invalid_existing_value", ["users", "email", email])
);
return;
}
throw new Error("it didn't throw");
});
},
LONG_TEST_TIMEOUT
);
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(
`${base_url}/api/v1/collections/password-reset-intents`,
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.post(
`${base_url}/api/v1/collections/password-reset-intents`,
{
email: "user@example.com",
}
)
).data;
assert.deepEqual(
{ email, token },
{
email: "user@example.com",
token: "it's a secret to everybody",
}
)
).data;
assert.deepEqual(
{ email, token },
{
email: "user@example.com",
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`,
{
email: "user@example.com",
}
);
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,34 +4,39 @@ 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 () =>
withProdApp(async ({ app, rest_api }) => {
const [user, session] = await createAdmin(app, rest_api);
await TestUtils.assertThrowsAsync(
async () => {
return rest_api.post(
`/api/v1/collections/user-roles`,
{
user: user.id,
},
session
);
},
(e: any) => {
assert.equal(
e?.response.data.data.field_messages.role?.message,
"Missing value for field 'role'."
);
}
);
}));
it(
"rejects when given an empty role",
async () =>
withProdApp(async ({ app, rest_api }) => {
const [user, session] = await createAdmin(app, rest_api);
await TestUtils.assertThrowsAsync(
async () => {
return rest_api.post(
`/api/v1/collections/user-roles`,
{
user: user.id,
},
session
);
},
(e: any) => {
assert.equal(
e?.response.data.data.field_messages.role?.message,
"Missing value for field 'role'."
);
}
);
}),
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,15 +3,18 @@ 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);
return withProdApp(async ({ base_url, rest_api }) => {
await rest_api.get(HelloURL);
await webhintURL(base_url + HelloURL);
// 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(HelloURL);
// await webhintHTML(response);
});
});
it(
"doesn't crash",
async function () {
return withProdApp(async ({ base_url, rest_api }) => {
await rest_api.get(HelloURL);
await webhintURL(base_url + HelloURL);
// 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(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", () =>
withProdApp(async ({ base_url }) => {
await webhintURL(`${base_url}/`);
}));
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,33 +23,39 @@ describe("Logout", () => {
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(LogoutURL);
},
{ name: "Error" }
);
});
});
it(
"doesn't crash",
async function () {
return withProdApp(async ({ rest_api }) => {
await assert.rejects(
async () => {
await rest_api.get(LogoutURL);
},
{ name: "Error" }
);
});
},
VERY_LONG_TEST_TIMEOUT
);
describe("logout test", () => {
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();
await page.getByPlaceholder("text").fill(username);
await page.getByPlaceholder("text").press("Tab");
await page.getByPlaceholder("password").fill(password);
await page.getByPlaceholder("password").press("Enter");
await page.waitForSelector(`a[href="${LogoutURL}"]`);
await page.getByRole("link", { name: "Logout" }).click();
await page.waitForSelector(`a[href="${SignInURL}"]`);
});
});
it(
"logout",
async function () {
await withProdApp(async ({ base_url }) => {
await page.goto(base_url);
await page.getByRole("link", { name: "Sign in" }).click();
await page.getByPlaceholder("text").click();
await page.getByPlaceholder("text").fill(username);
await page.getByPlaceholder("text").press("Tab");
await page.getByPlaceholder("password").fill(password);
await page.getByPlaceholder("password").press("Enter");
await page.waitForSelector(`a[href="${LogoutURL}"]`);
await page.getByRole("link", { name: "Logout" }).click();
await page.waitForSelector(`a[href="${SignInURL}"]`);
});
},
LONG_TEST_TIMEOUT
);
});
});

@ -1,103 +1,113 @@
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);
return withProdApp(async ({ base_url, rest_api }) => {
await rest_api.get(SignInURL);
await webhintURL(base_url + SignInURL);
// 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(SignInURL);
// await webhintHTML(response);
});
});
it(
"doesn't crash",
async function () {
return withProdApp(async ({ base_url, rest_api }) => {
await rest_api.get(SignInURL);
await webhintURL(base_url + SignInURL);
// 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(SignInURL);
// await webhintHTML(response);
});
},
VERY_LONG_TEST_TIMEOUT
);
describe("can access test", () => {
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();
await page.getByPlaceholder("text").fill(username);
await page.getByPlaceholder("text").press("Tab");
await page.getByPlaceholder("password").fill(password);
await page.getByPlaceholder("password").press("Enter");
await page.waitForSelector(`a[href="${LogoutURL}"]`);
await page.goto(base_url + SignInURL);
await page.waitForSelector('body:has-text("no access")');
await page.goto(base_url);
await page.getByRole("link", { name: "Logout" }).click();
await page.waitForSelector(`a[href="${SignInURL}"]`);
});
});
it(
"access url",
async function () {
await withProdApp(async ({ base_url }) => {
const { context, page } = await getPage();
await page.goto(base_url);
await page.getByRole("link", { name: "Sign in" }).click();
await page.getByPlaceholder("text").click();
await page.getByPlaceholder("text").fill(username);
await page.getByPlaceholder("text").press("Tab");
await page.getByPlaceholder("password").fill(password);
await page.getByPlaceholder("password").press("Enter");
await page.waitForSelector(`a[href="${LogoutURL}"]`);
await page.goto(base_url + SignInURL);
await page.waitForSelector('body:has-text("no access")');
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 () {
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();
await page.getByPlaceholder("text").fill("username20230720722");
await page.getByPlaceholder("text").press("Tab");
await page.getByPlaceholder("password").fill("test");
await page.getByPlaceholder("password").press("Enter");
await page.waitForSelector(".form-message");
});
});
it(
"wrong username",
async function () {
await withProdApp(async ({ base_url }) => {
const { context, page } = await getPage();
await page.goto(base_url);
await page.getByRole("link", { name: "Sign in" }).click();
await page.getByPlaceholder("text").click();
await page.getByPlaceholder("text").fill("username20230720722");
await page.getByPlaceholder("text").press("Tab");
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 () {
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();
await page.getByPlaceholder("text").fill(username);
await page.getByPlaceholder("text").press("Tab");
await page.getByPlaceholder("password").fill(password);
await page.getByPlaceholder("password").press("Enter");
await page.waitForSelector(`a[href="${LogoutURL}"]`);
await page.getByRole("link", { name: "Logout" }).click();
await page.waitForSelector(`a[href="${SignInURL}"]`);
});
});
it(
"correct username and password",
async function () {
await withProdApp(async ({ base_url }) => {
const { context, page } = await getPage();
await page.goto(base_url);
await page.getByRole("link", { name: "Sign in" }).click();
await page.getByPlaceholder("text").click();
await page.getByPlaceholder("text").fill(username);
await page.getByPlaceholder("text").press("Tab");
await page.getByPlaceholder("password").fill(password);
await page.getByPlaceholder("password").press("Enter");
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 () {
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();
await page.getByPlaceholder("text").fill(username);
await page.getByPlaceholder("text").press("Tab");
await page.getByPlaceholder("password").fill("asddasads20230720722");
await page.getByPlaceholder("password").press("Enter");
await page.waitForSelector(".form-message");
});
});
it(
"wrong password",
async function () {
await withProdApp(async ({ base_url }) => {
const { context, page } = await getPage();
await page.goto(base_url);
await page.getByRole("link", { name: "Sign in" }).click();
await page.getByPlaceholder("text").click();
await page.getByPlaceholder("text").fill(username);
await page.getByPlaceholder("text").press("Tab");
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,100 +36,110 @@ 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 () {
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").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 () {
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("dasdsa");
await page.getByPlaceholder("email").click();
await page
.getByPlaceholder("email")
.fill("asasdsdadsadss123asddsa@asdasca.com");
await page.getByPlaceholder("password").click();
await page.getByPlaceholder("password").fill("asddsa");
await page.getByRole("button", { name: "Wyślij" }).click();
await page.waitForSelector(".form-message.form-message--error");
});
});
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();
await page.getByPlaceholder("text").fill("ranomusername2023072722");
await page.getByPlaceholder("text").press("Tab");
await page.getByPlaceholder("email").fill(email);
await page.getByPlaceholder("email").press("Tab");
await page.getByPlaceholder("password").fill("asdasdasdasdasd");
await page.getByRole("button", { name: "Wyślij" }).click();
await page.waitForSelector(".form-message.form-message--error");
});
});
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").press("Tab");
await page.getByPlaceholder("password").fill("asdasdasdasdasd");
await page.getByRole("button", { name: "Wyślij" }).click();
await page.waitForSelector(".success-notify");
});
});
it(
"username is taken",
async function () {
await withProdApp(async ({ base_url }) => {
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").press("Tab");
await page.getByPlaceholder("password").fill("user12341234");
await page.getByRole("button", { name: "Wyślij" }).click();
await page.waitForSelector(".input__error");
});
},
VERY_LONG_TEST_TIMEOUT
);
it(
"password is too shot ",
async function () {
await withProdApp(async ({ base_url }) => {
await page.goto(base_url);
await page.getByRole("link", { name: "Sign up" }).click();
await page.getByPlaceholder("text").click();
await page.getByPlaceholder("text").fill("dasdsa");
await page.getByPlaceholder("email").click();
await page
.getByPlaceholder("email")
.fill("asasdsdadsadss123asddsa@asdasca.com");
await page.getByPlaceholder("password").click();
await page.getByPlaceholder("password").fill("asddsa");
await page.getByRole("button", { name: "Wyślij" }).click();
await page.waitForSelector(".form-message.form-message--error");
});
},
VERY_LONG_TEST_TIMEOUT
);
it(
"email is taken",
async function () {
await withProdApp(async ({ base_url }) => {
await page.goto(base_url);
await page.getByRole("link", { name: "Sign up" }).click();
await page.getByPlaceholder("text").click();
await page.getByPlaceholder("text").fill("ranomusername2023072722");
await page.getByPlaceholder("text").press("Tab");
await page.getByPlaceholder("email").fill(email);
await page.getByPlaceholder("email").press("Tab");
await page.getByPlaceholder("password").fill("asdasdasdasdasd");
await page.getByRole("button", { name: "Wyślij" }).click();
await page.waitForSelector(".form-message.form-message--error");
});
},
VERY_LONG_TEST_TIMEOUT
);
it(
"correct",
async function () {
await withProdApp(async ({ base_url }) => {
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").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 () {
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();
await page.getByPlaceholder("text").fill(username);
await page.getByPlaceholder("text").press("Tab");
await page.getByPlaceholder("password").fill(password);
await page.getByPlaceholder("password").press("Enter");
await page.waitForSelector(`a[href="${LogoutURL}"]`);
await page.goto(base_url + SignUpURL);
await page.waitForSelector('body:has-text("no access")');
await page.goto(base_url);
await page.getByRole("link", { name: "Logout" }).click();
await page.waitForSelector(`a[href="${SignInURL}"]`);
});
});
it(
"access url",
async function () {
await withProdApp(async ({ base_url }) => {
await page.goto(base_url);
await page.getByRole("link", { name: "Sign in" }).click();
await page.getByPlaceholder("text").click();
await page.getByPlaceholder("text").fill(username);
await page.getByPlaceholder("text").press("Tab");
await page.getByPlaceholder("password").fill(password);
await page.getByPlaceholder("password").press("Enter");
await page.waitForSelector(`a[href="${LogoutURL}"]`);
await page.goto(base_url + SignUpURL);
await page.waitForSelector('body:has-text("no access")');
await page.goto(base_url);
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,59 +40,55 @@ 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 () {
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();
await page.getByPlaceholder("text").fill(username);
await page.getByPlaceholder("text").press("Tab");
await page.getByPlaceholder("password").fill(password);
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.getByRole("button", { name: "Wyślij" }).click();
await page.waitForSelector(".form-message.form-message--success");
await page.locator("turbo-frame").getByRole("checkbox").check();
await page.locator("turbo-frame").getByRole("checkbox").uncheck();
await page
.locator("turbo-frame")
.getByRole("button", { name: "Delete" })
.click();
await page.getByRole("link", { name: "Logout" }).click();
await page.waitForSelector(`a[href="${SignInURL}"]`);
});
});
it(
"create and delete task",
async function () {
await withProdApp(async ({ base_url }) => {
await page.goto(base_url);
await page.getByRole("link", { name: "Sign in" }).click();
await page.getByPlaceholder("text").click();
await page.getByPlaceholder("text").fill(username);
await page.getByPlaceholder("text").press("Tab");
await page.getByPlaceholder("password").fill(password);
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.getByRole("button", { name: "Wyślij" }).click();
await page.waitForSelector(".form-message.form-message--success");
await page.locator("turbo-frame").getByRole("checkbox").check();
await page.locator("turbo-frame").getByRole("checkbox").uncheck();
await page
.locator("turbo-frame")
.getByRole("button", { name: "Delete" })
.click();
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 () {
await withProdApp(async ({ base_url }) => {
this.timeout(LONG_TEST_TIMEOUT);
await page.goto(base_url);
try {
await page.waitForSelector(`a[href="${SignInURL}"]`);
await page.goto(base_url + TodoURL);
await page.waitForSelector('body:has-text("no access")');
} catch (error) {
console.error(error);
}
});
});
it(
"access url",
async function () {
await withProdApp(async ({ base_url }) => {
await page.goto(base_url);
try {
await page.waitForSelector(`a[href="${SignInURL}"]`);
await page.goto(base_url + TodoURL);
await page.waitForSelector('body:has-text("no access")');
} catch (error) {
console.error(error);
}
});
},
LONG_TEST_TIMEOUT
);
});
});

@ -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 }
}

@ -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…
Cancel
Save