Remove webhint

This commit is contained in:
Kuba Orlik 2025-05-20 19:16:23 +02:00
parent 1182803f1b
commit b548dda558
15 changed files with 12 additions and 11274 deletions

View File

@ -42,14 +42,3 @@ And then
npm run test npm run test
``` ```
The tests don't run webhint by default - it's delegated to run on Jenkins.
If Jenkins complains about a webhint issue and you'd like to reproduce that on your local machine, run
```
npm run full-test
```
The tests run in pararell mode by default, to speed things up. Because of that, the
`.only` syntax doesn't work. To run tests without pararell mode, run `npm run full-test
--serial` - you can then use the `.only` syntax to run a particular test

View File

@ -28,7 +28,6 @@ CONTAINER_ID=$(docker compose run -d --user="$UID" \
-e "SEALIOUS_MAILCATCHER_HOST=mailcatcher" \ -e "SEALIOUS_MAILCATCHER_HOST=mailcatcher" \
-e "SEALIOUS_MAILCATCHER_API_PORT=1080" \ -e "SEALIOUS_MAILCATCHER_API_PORT=1080" \
-e "SEALIOUS_MAILCATCHER_SMTP_PORT=1025" \ -e "SEALIOUS_MAILCATCHER_SMTP_PORT=1025" \
-e "WITH_WEBHINT=TRUE" \
-e "FORCE_COLOR=0" \ -e "FORCE_COLOR=0" \
test npm run test-reports) test npm run test-reports)

View File

@ -15,10 +15,8 @@
"postbuild": "npm run typecheck && npm run lint", "postbuild": "npm run typecheck && npm run lint",
"watch": "multiple-scripts-tmux -p watch", "watch": "multiple-scripts-tmux -p watch",
"reset-db": "docker compose down -v && docker compose up -d", "reset-db": "docker compose down -v && docker compose up -d",
"install-test-deps": "npx playwright install firefox && cd webhint && npm install && ./use-fork.sh",
"pretest": "npm run build && docker compose up -d", "pretest": "npm run build && docker compose up -d",
"test": "node test.cjs", "test": "node test.cjs",
"full-test": "WITH_WEBHINT=TRUE npm run test",
"prepare": "husky", "prepare": "husky",
"lint": "eslint src", "lint": "eslint src",
"lint-report": "npm run --silent lint -- --format json > .eslint-result.json", "lint-report": "npm run --silent lint -- --format json > .eslint-result.json",

View File

@ -2,7 +2,6 @@ import axios from "axios";
import assert from "assert"; import assert from "assert";
import type TheApp from "../app.js"; import type TheApp from "../app.js";
import { withProdApp } from "../test_utils/with-prod-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 () { describe("password-reset-intents", function () {
//ts-ignore //ts-ignore
@ -34,7 +33,7 @@ describe("password-reset-intents", function () {
} }
throw new Error("it didn't throw"); throw new Error("it didn't throw");
}); });
}).timeout(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 }) => { withProdApp(async ({ app, base_url }) => {
@ -54,7 +53,7 @@ describe("password-reset-intents", function () {
token: "it's a secret to everybody", token: "it's a secret to everybody",
} }
); );
})).timeout(LONG_TEST_TIMEOUT); }));
it("tells you if the email address is malformed", async () => it("tells you if the email address is malformed", async () =>
withProdApp(async ({ app, base_url }) => { withProdApp(async ({ app, base_url }) => {

View File

@ -4,7 +4,6 @@ import { Context, TestUtils } from "sealious";
import { withProdApp } from "../test_utils/with-prod-app.js"; import { withProdApp } from "../test_utils/with-prod-app.js";
import { createAdmin, createAUser } from "../test_utils/users.js"; import { createAdmin, createAUser } from "../test_utils/users.js";
import Users from "./users.js"; import Users from "./users.js";
import { LONG_TEST_TIMEOUT } from "../test_utils/webhint.js";
describe("user-roles", () => { describe("user-roles", () => {
it("rejects when given an empty role", async () => it("rejects when given an empty role", async () =>
@ -28,7 +27,7 @@ describe("user-roles", () => {
); );
} }
); );
})).timeout(LONG_TEST_TIMEOUT); }));
it("accepts correct dataset", async () => it("accepts correct dataset", async () =>
withProdApp(async ({ app, base_url, rest_api }) => { withProdApp(async ({ app, base_url, rest_api }) => {

View File

@ -1,4 +1,3 @@
import { LONG_TEST_TIMEOUT } from "../test_utils/webhint.js";
import { withProdApp } from "../test_utils/with-prod-app.js"; import { withProdApp } from "../test_utils/with-prod-app.js";
describe("roles", () => { describe("roles", () => {
@ -22,5 +21,5 @@ describe("roles", () => {
user: admin.id, user: admin.id,
role: "admin", role: "admin",
}); });
})).timeout(LONG_TEST_TIMEOUT); }));
}); });

View File

@ -1,20 +1,14 @@
import { withProdApp } from "../test_utils/with-prod-app.js"; import { withProdApp } from "../test_utils/with-prod-app.js";
import { VERY_LONG_TEST_TIMEOUT, webhintURL } from "../test_utils/webhint.js";
import { AdminURL } from "./urls.js"; import { AdminURL } from "./urls.js";
import { getBrowser } from "../test_utils/browser-creator.js"; import { getBrowser } from "../test_utils/browser-creator.js";
import type { Browser, BrowserContext, Page } from "@playwright/test"; import type { Browser, BrowserContext, Page } from "@playwright/test";
describe("Admin webhint", () => { describe("Admin", () => {
it("doesn't crash", async function () { it("doesn't crash", async function () {
return withProdApp(async ({ base_url, rest_api }) => { return withProdApp(async ({ rest_api }) => {
await rest_api.get(AdminURL); await rest_api.get(AdminURL);
await webhintURL(base_url + AdminURL);
// 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(AdminURL);
// await webhintHTML(response);
}); });
}).timeout(VERY_LONG_TEST_TIMEOUT); });
}); });
describe("Admin", () => { describe("Admin", () => {
@ -36,5 +30,5 @@ describe("Admin", () => {
return withProdApp(async ({ base_url }) => { return withProdApp(async ({ base_url }) => {
await page.goto(base_url + AdminURL); await page.goto(base_url + AdminURL);
}); });
}).timeout(VERY_LONG_TEST_TIMEOUT); });
}); });

View File

@ -1,20 +1,14 @@
import { withProdApp } from "../../test_utils/with-prod-app.js"; import { withProdApp } from "../../test_utils/with-prod-app.js";
import { VERY_LONG_TEST_TIMEOUT, webhintURL } from "../../test_utils/webhint.js";
import { ShowFirstRowDemoURL } from "../urls.js"; import { ShowFirstRowDemoURL } from "../urls.js";
import { getBrowser } from "../../test_utils/browser-creator.js"; import { getBrowser } from "../../test_utils/browser-creator.js";
import type { Browser, BrowserContext, Page } from "@playwright/test"; import type { Browser, BrowserContext, Page } from "@playwright/test";
describe("ShowFirstRowDemo webhint", () => { describe("ShowFirstRowDemo", () => {
it("doesn't crash", async function () { it("doesn't crash", async function () {
return withProdApp(async ({ base_url, rest_api }) => { return withProdApp(async ({ rest_api }) => {
await rest_api.get(ShowFirstRowDemoURL); await rest_api.get(ShowFirstRowDemoURL);
await webhintURL(base_url + ShowFirstRowDemoURL);
// 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(ShowFirstRowDemoURL);
// await webhintHTML(response);
}); });
}).timeout(VERY_LONG_TEST_TIMEOUT); });
}); });
describe("ShowFirstRowDemo", () => { describe("ShowFirstRowDemo", () => {
@ -36,5 +30,5 @@ describe("ShowFirstRowDemo", () => {
return withProdApp(async ({ base_url }) => { return withProdApp(async ({ base_url }) => {
await page.goto(base_url + ShowFirstRowDemoURL); await page.goto(base_url + ShowFirstRowDemoURL);
}); });
}).timeout(VERY_LONG_TEST_TIMEOUT); });
}); });

View File

@ -1,40 +0,0 @@
import { withProdApp } from "../test_utils/with-prod-app.js";
import { VERY_LONG_TEST_TIMEOUT, webhintURL } from "../test_utils/webhint.js";
import { HelloPageURL } from "./urls.js";
import { getBrowser } from "../test_utils/browser-creator.js";
import type { Browser, BrowserContext, Page } from "@playwright/test";
describe("HelloPage webhint", () => {
it("doesn't crash", async function () {
return withProdApp(async ({ base_url, rest_api }) => {
await rest_api.get(HelloPageURL);
await webhintURL(base_url + HelloPageURL);
// 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(HelloPageURL);
// await webhintHTML(response);
});
}).timeout(VERY_LONG_TEST_TIMEOUT);
});
describe("HelloPage", () => {
let page: Page;
let browser: Browser;
let context: BrowserContext;
beforeEach(async () => {
browser = await getBrowser();
context = await browser.newContext();
page = await context.newPage();
});
afterEach(async () => {
await context.close();
});
it("works as expected", async function () {
return withProdApp(async ({ base_url }) => {
await page.goto(base_url + HelloPageURL);
});
}).timeout(VERY_LONG_TEST_TIMEOUT);
});

View File

@ -1,49 +0,0 @@
import _locreq from "locreq";
const locreq = _locreq(import.meta.dirname);
import { spawn } from "child_process";
import { hasShape, is, predicates } from "@sealcode/ts-predicates";
import { promises as fs } from "fs";
import chalk from "chalk";
export const LONG_TEST_TIMEOUT = 100 * 1000;
export const VERY_LONG_TEST_TIMEOUT = 300 * 1000;
export async function webhintURL(url: string, config = locreq.resolve(".hintrc")) {
// eslint-disable-next-line no-console
console.log("scanning with webhint....", url);
if (process.env.WITH_WEBHINT !== "TRUE") {
// eslint-disable-next-line no-console
console.log(
chalk.yellow(
"skipping webhint tests. Run 'WITH_WEBHINT=true npm run test' to run full tests or run them on Jenkins"
)
);
return;
}
try {
const subprocess = spawn(
"node",
[locreq.resolve("webhint/node_modules/.bin/hint"), "--config", config, url],
{ cwd: locreq.resolve("webhint") } // to prevent webhint from trying to parese source code
);
subprocess.stderr.on("data", (b) => console.error(String(b)));
// eslint-disable-next-line no-console
subprocess.stdout.on("data", (b) => console.log(String(b)));
await new Promise<void>((resolve, reject) => {
subprocess.on("close", (code) =>
code === 0 ? resolve() : reject(new Error("Webhint tests failed"))
);
});
} catch (e) {
if (is(e, predicates.object) && hasShape({ stdout: predicates.string }, e)) {
throw new Error(e.stdout);
} else {
throw e;
}
}
}
export async function webhintHTML(html: string) {
await fs.writeFile("/tmp/index.html", html);
await webhintURL("/tmp/index.html", locreq.resolve(".hintrc.local.json"));
}

View File

@ -1,9 +0,0 @@
#!/usr/bin/env bash
cd webhint
while true; do
wget localhost:8080/all-components --output-document ./output.html
npx hint --config ../hintrc.local.json ./output.html
if [ "$?" != 0 ]; then
exit 1;
fi;
done

View File

@ -1 +0,0 @@
// this file is just a placeholder to have a clean webhint working directory

11109
webhint/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +0,0 @@
{
"name": "webhint",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@hint/configuration-web-recommended": "^8.2.23",
"@hint/formatter-codeframe": "^3.1.35",
"@hint/hint-doctype": "^3.3.26",
"@hint/hint-no-broken-links": "^4.2.26",
"hint": "^7.1.11",
"@hint/utils-dom": "^2.2.4"
}
}

View File

@ -1,5 +0,0 @@
#!/bin/bash
# Using the fork manually until https://github.com/webhintio/hint/pull/5876 is landed
wget https://cdn.sealco.de/file/download/lsx3pa5guz2udjaaqowg/PHID-FILE-bnqnugnra4kiielhumvr/axe.js --output-document node_modules/@hint/hint-axe/dist/src/util/axe.js