Page MenuHomeSealhub

multiform.test.ts
No OneTemporary

multiform.test.ts

import Router from "@koa/router";
import Koa from "koa";
import axios from "axios";
import { Browser, Page } from "playwright";
import { expect } from "@playwright/test";
import { FlatTemplatable, tempstream } from "tempstream";
import { mount } from "../mount.js";
import { Multiform } from "./multiform.js";
import { assertThrowsAsync } from "../utils/utils.js";
import { form_factory } from "./form.test.js";
import { getBrowser } from "../utils/browser-creator.js";
import { SimpleFormField } from "./fields/simple-form-field.js";
import { Form } from "./form.js";
import { FormHeader } from "./controls/form-header.js";
import { SimpleInput } from "./controls/simple-input.js";
import { Mountable } from "../page/mountable.js";
import { FormDataValue, FormMessage } from "./form-types.js";
import { EmailField } from "./fields/email.js";
import getPort from "get-port";
const port = await getPort();
console.log(`Using port ${port} form multiform.test.ts`);
const fields1 = {
email: new SimpleFormField(true),
};
const form1 = new (class extends Form<typeof fields1, void> {
defaultSuccessMessage = "Form1 done!";
controls = [new FormHeader("form1"), new SimpleInput(fields1.email)];
fields = fields1;
onSubmit() {
return;
}
})();
const fields2 = {
name: new SimpleFormField(true),
};
const form2 = new (class extends Form<Record<never, unknown>, void> {
defaultSuccessMessage = "Form2 done!";
controls = [new FormHeader("form2"), new SimpleInput(fields2.name)];
fields = fields2;
onSubmit() {
return;
}
})();
function multiform_factory(
canAccessFun1?: Mountable["canAccess"],
canAccessFun2?: Mountable["canAccess"]
): Multiform {
return new (class extends Multiform {
name = "multiform_test";
forms = {
form1: form_factory(canAccessFun1),
form2: form_factory(canAccessFun2),
};
async render(...args: Parameters<Multiform["render"]>): Promise<FlatTemplatable> {
return tempstream/* HTML */ `<!DOCTYPE html>
<html>
<head>
<title>Multiform Test - Sealgen</title>
<script type="module">
import hotwiredTurbo from "https://cdn.skypack.dev/pin/@hotwired/turbo@v7.0.0-9XNv1By6uiqRlBzQLO2d/mode=imports,min/optimized/@hotwired/turbo.js";
</script>
</head>
<body>
${super.render(...args)}
</body>
</html>`;
}
})();
}
async function tests(js_enabled: boolean) {
let page: Page;
before(async () => {
const browser = await getBrowser();
const context = await browser.newContext({
javaScriptEnabled: js_enabled,
});
page = await context.newPage();
await page.goto(`http://localhost:${port}`);
await page.getByLabel("email").click();
await page.getByLabel("email").fill("sample1");
await page.getByLabel("name").click();
await page.getByLabel("name").fill("sample2");
await page.locator("#multiform_test_form1_submit").click();
});
it("checking whether only one submit handler is run", async () => {
await page.getByText("Form1 done!").click();
await assertThrowsAsync(async () => {
return page.getByText("Form2 done!").click({ timeout: 500 });
});
});
it("checking whether the input in the not submitted form prevails", async () => {
await expect(page.getByLabel("name")).toHaveValue("sample2");
});
}
async function general_form_validation_e2e_tests(js_enabled: boolean) {
let browser: Browser;
let page: Page;
browser = await getBrowser();
const context = await browser.newContext({
javaScriptEnabled: js_enabled,
});
page = await context.newPage();
await page.goto(`http://localhost:${port}`);
await page.getByPlaceholder("text").click();
await page.getByPlaceholder("text").fill("incorrect");
await page.getByPlaceholder("password").click();
await page.getByPlaceholder("password").fill("test");
await page.locator("#multiform_test_form2_submit").click();
await assertThrowsAsync(async () => {
await page.getByText("Incorrect input").click({ timeout: 500 });
});
}
async function individual_field_validation_e2e_tests(javaScriptEnabled: boolean) {
let browser: Browser;
let page: Page;
before(async () => {
browser = await getBrowser();
const context = await browser.newContext({
javaScriptEnabled,
});
page = await context.newPage();
await page.goto(`http://localhost:${port}`);
});
it("validation message shows when incorrect input is given", async () => {
await page.getByPlaceholder("text").click();
await page.getByPlaceholder("text").fill("notanemail");
await page.locator("#multiform_test_form1_submit").click();
await page.getByText("Please enter a proper email address").click();
});
it("validation message doesn't show when correct input is given", async () => {
await page.getByPlaceholder("text").click();
await page.getByPlaceholder("text").fill("yes@an.email");
await page.locator("#multiform_test_form1_submit").click();
assertThrowsAsync(async () => {
return page.getByText("Please enter a proper email address").click({ timeout: 500 });
});
});
}
describe("multiform test", () => {
describe("basic tests", async () => {
let server: ReturnType<Koa["listen"]>;
before(async () => {
const app = new Koa();
const router = new Router();
mount(
router,
"/",
new (class extends Multiform {
name = "multiform_test";
forms = { form1, form2 };
async render(
ctx: Koa.Context,
messages: FormMessage[],
prerenderedForms?: Record<string, FlatTemplatable | undefined>,
show_field_errors = true
): Promise<FlatTemplatable> {
return tempstream/* HTML */ `<!DOCTYPE html>
<html>
<head>
<title>Multiform Test - Sealgen</title>
<script type="module">
import hotwiredTurbo from "https://cdn.skypack.dev/pin/@hotwired/turbo@v7.0.0-9XNv1By6uiqRlBzQLO2d/mode=imports,min/optimized/@hotwired/turbo.js";
</script>
</head>
<body>
${super.render(
ctx,
messages,
prerenderedForms,
show_field_errors
)}
</body>
</html>`;
}
})(),
true
);
app.use(router.routes()).use(router.allowedMethods());
server = app.listen(port);
});
after(() => {
server.close();
});
describe("turbolinks + js enabled", async () => tests(true));
describe("turbolinks + js disabled", async () => tests(false));
});
describe("canAccess", async () => {
let page: Page;
let server: ReturnType<Koa["listen"]>;
describe("allow access to both forms when both canAccess return true", async () => {
before(async () => {
const app = new Koa();
const router = new Router();
mount(
router,
"/",
multiform_factory(
async (
ctx: Koa.Context
): Promise<{ canAccess: boolean; message: string }> => {
return { canAccess: true, message: "" };
},
async (
ctx: Koa.Context
): Promise<{ canAccess: boolean; message: string }> => {
return { canAccess: true, message: "" };
}
),
true
);
app.use(router.routes()).use(router.allowedMethods());
server = app.listen(port);
const browser = await getBrowser();
const context = await browser.newContext();
page = await context.newPage();
});
after(async () => {
server.close();
});
it("check wether it renders", async () => {
const response = await page.goto(`http://localhost:${port}`);
if (response?.status() != 200) {
throw new Error(
`Should return 200 status and it returns ${response?.status()}`
);
}
await page.locator("#form1").getByText("This is a test:").click();
await page.locator("#form2").getByText("This is a test:").click();
});
it("check wether you can submit through http (axios)", async () => {
await axios.post(
`http://localhost:${port}/form2`,
{
form2__text: "pass",
},
{
validateStatus: (status: number) => {
if (status == 422) return true;
return false;
},
}
);
});
});
describe("deny access to both forms", async () => {
before(async () => {
const app = new Koa();
const router = new Router();
mount(
router,
"/",
multiform_factory(
async (
ctx: Koa.Context
): Promise<{ canAccess: boolean; message: string }> => {
return { canAccess: false, message: "" };
},
async (
ctx: Koa.Context
): Promise<{ canAccess: boolean; message: string }> => {
return { canAccess: false, message: "" };
}
),
true
);
app.use(router.routes()).use(router.allowedMethods());
server = app.listen(port);
const browser = await getBrowser();
const context = await browser.newContext();
page = await context.newPage();
});
after(async () => {
server.close();
});
it("check wether forms didnt render", async () => {
await page.goto(`http://localhost:${port}`);
await assertThrowsAsync(async () => {
return page
.locator("#form1")
.getByText("This is a test:")
.click({ timeout: 300 });
});
});
it("check wether it's possible to submit through http", async () => {
await axios.post(
`http://localhost:${port}/form2`,
{
form2__text: "pass",
},
{
validateStatus: (status: number) => {
if (status == 403) return true;
return false;
},
}
);
});
});
describe("allow access to one form, deny to the other", async () => {
before(async () => {
const app = new Koa();
const router = new Router();
mount(
router,
"/",
multiform_factory(
async (
ctx: Koa.Context
): Promise<{ canAccess: boolean; message: string }> => {
return { canAccess: true, message: "" };
},
async (
ctx: Koa.Context
): Promise<{ canAccess: boolean; message: string }> => {
return { canAccess: false, message: "" };
}
),
true
);
app.use(router.routes()).use(router.allowedMethods());
server = app.listen(port);
const browser = await getBrowser();
const context = await browser.newContext({});
page = await context.newPage();
});
after(async () => {
server.close();
});
it("check wether form1 renders", async () => {
await page.goto(`http://localhost:${port}`);
await page.locator("#form1").getByText("This is a test:").click({ timeout: 300 });
});
it("check wether it's possible to submit to form1 through http", async () => {
await axios.post(
`http://localhost:${port}/form1`,
{
form1__text: "pass",
},
{
validateStatus: (status: number) => {
if (status == 422) return true;
return false;
},
}
);
});
it("check wether form2 does not render", async () => {
await page.goto(`http://localhost:${port}`);
await assertThrowsAsync(async () => {
return page
.locator("#form2")
.getByText("This is a test:")
.click({ timeout: 300 });
});
});
it("check wether it's possible to submit to form2 through http", async () => {
await axios.post(
`http://localhost:${port}/form2`,
{
form2__text: "pass",
},
{
validateStatus: (status: number) => {
if (status == 403) return true;
return false;
},
}
);
});
});
});
describe("validation e2e", async () => {
describe("basic tests", async () => {
let server: ReturnType<Koa["listen"]>;
before(async () => {
const app = new Koa();
const router = new Router();
mount(
router,
"/",
new (class extends Multiform {
name = "multiform_test";
forms = {
form1: new (class extends Form<typeof fields1, void> {
fields = fields1;
submitButtonText = "Submit";
controls = [
new SimpleInput(fields1.email, {
label: "This is a test:",
type: "text",
}),
];
async onSubmit() {
return;
}
async validateValues(
ctx: Koa.Context,
data: Record<string, FormDataValue>
): Promise<{ valid: boolean; error: string }> {
if (data.email === "incorrect")
return {
valid: false,
error: "Incorrect input",
};
return { valid: true, error: "" };
}
})(),
form2: form_factory(),
};
async render(
...args: Parameters<Multiform["render"]>
): Promise<FlatTemplatable> {
return tempstream/* HTML */ `<!DOCTYPE html>
<html>
<head>
<title>Multiform Test - Sealgen</title>
<script type="module">
import hotwiredTurbo from "https://cdn.skypack.dev/pin/@hotwired/turbo@v7.0.0-9XNv1By6uiqRlBzQLO2d/mode=imports,min/optimized/@hotwired/turbo.js";
</script>
</head>
<body>
${super.render(...args)}
</body>
</html>`;
}
})(),
true
);
app.use(router.routes()).use(router.allowedMethods());
server = app.listen(port);
});
after(async () => {
server.close();
});
it("js enabled", async () => general_form_validation_e2e_tests(true));
it("js disabled", async () => general_form_validation_e2e_tests(false));
});
describe("field specific validation", async () => {
let server: ReturnType<Koa["listen"]>;
before(async () => {
const app = new Koa();
const router = new Router();
const fields = {
text: new EmailField(true),
};
mount(
router,
"/",
new (class extends Multiform {
name = "multiform_test";
forms = {
form1: new (class extends Form<typeof fields, void> {
fields = fields;
submitButtonText = "Submit";
controls = [
new SimpleInput(fields.text, {
label: "This is a test:",
type: "text",
}),
];
async onSubmit() {
return;
}
})(),
form2: form_factory(),
};
async render(
...args: Parameters<Multiform["render"]>
): Promise<FlatTemplatable> {
return tempstream/* HTML */ `<!DOCTYPE html>
<html>
<head>
<title>Multiform Test - Sealgen</title>
<script type="module">
import hotwiredTurbo from "https://cdn.skypack.dev/pin/@hotwired/turbo@v7.0.0-9XNv1By6uiqRlBzQLO2d/mode=imports,min/optimized/@hotwired/turbo.js";
</script>
</head>
<body>
${super.render(...args)}
</body>
</html>`;
}
})(),
true
);
app.use(router.routes()).use(router.allowedMethods());
server = app.listen(port);
});
after(async () => {
server.close();
});
describe("js enabled", async () => individual_field_validation_e2e_tests(true));
describe("js disabled", async () => individual_field_validation_e2e_tests(false));
});
});
});

File Metadata

Mime Type
text/html
Expires
Tue, Dec 24, 14:02 (20 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
557157
Default Alt Text
multiform.test.ts (14 KB)

Event Timeline