everywhere-qa 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scoring.js","sourceRoot":"","sources":["../src/scoring.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { Finding } from "./types.js";
2
+ export declare function scanSource(repo: string): Promise<Finding[]>;
@@ -0,0 +1,63 @@
1
+ import { readFile, readdir } from "node:fs/promises";
2
+ import { extname, join, relative } from "node:path";
3
+ import { finding } from "./findings.js";
4
+ const sourceExtensions = new Set([".ts", ".tsx", ".js", ".jsx", ".css", ".scss"]);
5
+ const ignored = new Set(["node_modules", ".next", "dist", "build", "coverage", ".git"]);
6
+ async function collectFiles(root, current = root, files = []) {
7
+ if (files.length >= 500)
8
+ return files;
9
+ for (const entry of await readdir(current, { withFileTypes: true })) {
10
+ if (ignored.has(entry.name))
11
+ continue;
12
+ const path = join(current, entry.name);
13
+ if (entry.isDirectory())
14
+ await collectFiles(root, path, files);
15
+ else if (sourceExtensions.has(extname(entry.name)))
16
+ files.push(path);
17
+ if (files.length >= 500)
18
+ break;
19
+ }
20
+ return files;
21
+ }
22
+ export async function scanSource(repo) {
23
+ const findings = [];
24
+ let files;
25
+ try {
26
+ files = await collectFiles(repo);
27
+ }
28
+ catch {
29
+ return findings;
30
+ }
31
+ for (const file of files) {
32
+ const text = await readFile(file, "utf8");
33
+ const display = relative(repo, file).replaceAll("\\", "/");
34
+ if (/\b(margin|padding)-(left|right)\s*:|(^|[;{\s])(left|right)\s*:/m.test(text)) {
35
+ findings.push(finding({
36
+ ruleId: "source-physical-direction",
37
+ pillar: "rtl",
38
+ severity: "minor",
39
+ scenario: "source-review",
40
+ selector: display,
41
+ message: "Physical left/right CSS may not mirror in right-to-left layouts.",
42
+ evidence: display,
43
+ confidence: "heuristic",
44
+ remediation: "Review this file and prefer logical properties such as margin-inline-start or inset-inline-end."
45
+ }));
46
+ }
47
+ if (/(["'`])(?:US\$|\$)\s?\d|\d\/(?:\d{1,2})\/\d{2,4}/.test(text)) {
48
+ findings.push(finding({
49
+ ruleId: "source-locale-literal",
50
+ pillar: "locale",
51
+ severity: "moderate",
52
+ scenario: "source-review",
53
+ selector: display,
54
+ message: "A currency or date literal may assume one locale.",
55
+ evidence: display,
56
+ confidence: "heuristic",
57
+ remediation: "Confirm the value is intentional; otherwise format it with Intl.NumberFormat or Intl.DateTimeFormat."
58
+ }));
59
+ }
60
+ }
61
+ return findings.slice(0, 30);
62
+ }
63
+ //# sourceMappingURL=source-scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-scan.js","sourceRoot":"","sources":["../src/source-scan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAGxC,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAClF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;AAExF,KAAK,UAAU,YAAY,CAAC,IAAY,EAAE,OAAO,GAAG,IAAI,EAAE,QAAkB,EAAE;IAC5E,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,KAAK,CAAC;IACtC,KAAK,MAAM,KAAK,IAAI,MAAM,OAAO,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACpE,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,SAAS;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,KAAK,CAAC,WAAW,EAAE;YAAE,MAAM,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;aAC1D,IAAI,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrE,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG;YAAE,MAAM;IACjC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,IAAI,KAAe,CAAC;IACpB,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC3D,IAAI,iEAAiE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACjF,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;gBACpB,MAAM,EAAE,2BAA2B;gBACnC,MAAM,EAAE,KAAK;gBACb,QAAQ,EAAE,OAAO;gBACjB,QAAQ,EAAE,eAAe;gBACzB,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,kEAAkE;gBAC3E,QAAQ,EAAE,OAAO;gBACjB,UAAU,EAAE,WAAW;gBACvB,WAAW,EAAE,iGAAiG;aAC/G,CAAC,CAAC,CAAC;QACN,CAAC;QACD,IAAI,kDAAkD,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAClE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;gBACpB,MAAM,EAAE,uBAAuB;gBAC/B,MAAM,EAAE,QAAQ;gBAChB,QAAQ,EAAE,UAAU;gBACpB,QAAQ,EAAE,eAAe;gBACzB,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,mDAAmD;gBAC5D,QAAQ,EAAE,OAAO;gBACjB,UAAU,EAAE,WAAW;gBACvB,WAAW,EAAE,sGAAsG;aACpH,CAAC,CAAC,CAAC;QACN,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,145 @@
1
+ export type Pillar = "accessibility" | "rtl" | "locale" | "resilience";
2
+ export type Severity = "critical" | "serious" | "moderate" | "minor";
3
+ export type Confidence = "deterministic" | "heuristic";
4
+ export type ScenarioKind = "accessibility" | "rtl" | "text-expansion" | "resilience";
5
+ export type GatePolicy = "off" | "regression";
6
+ export interface Viewport {
7
+ width: number;
8
+ height: number;
9
+ }
10
+ export interface NetworkProfile {
11
+ latencyMs: number;
12
+ downloadKbps: number;
13
+ uploadKbps: number;
14
+ }
15
+ export interface AuditProfiles {
16
+ accessibility: {
17
+ locale: string;
18
+ viewport: Viewport;
19
+ };
20
+ rtl: {
21
+ locale: string;
22
+ timezoneId: string;
23
+ viewport: Viewport;
24
+ };
25
+ textExpansion: {
26
+ locale: string;
27
+ viewport: Viewport;
28
+ ratio: number;
29
+ };
30
+ resilience: {
31
+ locale: string;
32
+ timezoneId: string;
33
+ viewport: Viewport;
34
+ network: NetworkProfile;
35
+ };
36
+ }
37
+ export interface AuditPage {
38
+ id: string;
39
+ url: string;
40
+ }
41
+ export interface ResolvedAuditConfig {
42
+ pages: AuditPage[];
43
+ profiles: AuditProfiles;
44
+ profileSignature: string;
45
+ isDefault: boolean;
46
+ }
47
+ export interface ScenarioResult {
48
+ id: string;
49
+ kind: ScenarioKind;
50
+ label: string;
51
+ pageId: string;
52
+ pageUrl: string;
53
+ locale: string;
54
+ viewport: Viewport;
55
+ durationMs: number;
56
+ screenshot: string;
57
+ status: "passed" | "completed-with-findings";
58
+ }
59
+ export interface Finding {
60
+ id: string;
61
+ ruleId: string;
62
+ pillar: Pillar;
63
+ severity: Severity;
64
+ scenario: string;
65
+ pageId?: string;
66
+ pageUrl?: string;
67
+ selector: string;
68
+ message: string;
69
+ evidence: string;
70
+ confidence: Confidence;
71
+ remediation: string;
72
+ helpUrl?: string;
73
+ }
74
+ export interface Scores {
75
+ overall: number;
76
+ accessibility: number;
77
+ rtl: number;
78
+ locale: number;
79
+ resilience: number;
80
+ }
81
+ export interface PageScores {
82
+ pageId: string;
83
+ pageUrl: string;
84
+ scores: Scores;
85
+ }
86
+ export interface VisualComparison {
87
+ scenarioId: string;
88
+ kind: ScenarioKind;
89
+ pageId: string;
90
+ label: string;
91
+ beforeScreenshot: string;
92
+ afterScreenshot: string;
93
+ }
94
+ export interface GateResult {
95
+ policy: GatePolicy;
96
+ status: "passed" | "failed" | "not-run";
97
+ reasons: string[];
98
+ }
99
+ export interface VerificationDelta {
100
+ baselineRunId: string;
101
+ fixed: Finding[];
102
+ remaining: Finding[];
103
+ introduced: Finding[];
104
+ scoreChange: number;
105
+ visualComparisons: VisualComparison[];
106
+ gate: GateResult;
107
+ }
108
+ export interface AuditReport {
109
+ schemaVersion: "1.1";
110
+ runId: string;
111
+ target: {
112
+ url: string;
113
+ repo?: string;
114
+ pages: AuditPage[];
115
+ profileSignature: string;
116
+ };
117
+ generatedAt: string;
118
+ tools: {
119
+ everywhereQa: string;
120
+ playwright: string;
121
+ axeCore: string;
122
+ };
123
+ scenarios: ScenarioResult[];
124
+ findings: Finding[];
125
+ advisories: Finding[];
126
+ scores: Scores;
127
+ pageScores: PageScores[];
128
+ summary: {
129
+ deterministic: number;
130
+ advisory: number;
131
+ critical: number;
132
+ };
133
+ verification?: VerificationDelta;
134
+ disclaimer: string;
135
+ }
136
+ export interface AuditOptions {
137
+ url: string;
138
+ repo?: string;
139
+ outDir: string;
140
+ timeoutMs?: number;
141
+ config: ResolvedAuditConfig;
142
+ baseline?: AuditReport;
143
+ baselineDir?: string;
144
+ gatePolicy?: GatePolicy;
145
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "everywhere-qa",
3
+ "version": "0.2.0",
4
+ "description": "Deterministic global-readiness audit engine for Everywhere QA",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "bin": {
8
+ "everywhere": "dist/cli.js"
9
+ },
10
+ "main": "dist/index.js",
11
+ "types": "dist/index.d.ts",
12
+ "files": ["dist", "README.md", "LICENSE"],
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/GuduruBharath-hub/EverywhereQA.git",
16
+ "directory": "packages/engine"
17
+ },
18
+ "homepage": "https://everywhere-qa-demo-2ifz.vercel.app/",
19
+ "bugs": "https://github.com/GuduruBharath-hub/EverywhereQA/issues",
20
+ "keywords": ["accessibility", "localization", "rtl", "playwright", "codex", "qa"],
21
+ "publishConfig": { "access": "public" },
22
+ "scripts": {
23
+ "build": "tsc -p tsconfig.json",
24
+ "typecheck": "tsc -p tsconfig.json --noEmit",
25
+ "test": "vitest run"
26
+ },
27
+ "dependencies": {
28
+ "@axe-core/playwright": "4.12.1",
29
+ "axe-core": "4.12.1",
30
+ "playwright": "1.61.1"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^22.15.30",
34
+ "typescript": "^5.8.3",
35
+ "vitest": "^3.2.4"
36
+ },
37
+ "engines": {
38
+ "node": ">=20"
39
+ }
40
+ }