ScuttleBot

scuttlebot / tests / e2e / node_modules / playwright / lib / runner / projectUtils.js
Source Blame History 241 lines
f7eb47b… lmata 1 "use strict";
f7eb47b… lmata 2 var __create = Object.create;
f7eb47b… lmata 3 var __defProp = Object.defineProperty;
f7eb47b… lmata 4 var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
f7eb47b… lmata 5 var __getOwnPropNames = Object.getOwnPropertyNames;
f7eb47b… lmata 6 var __getProtoOf = Object.getPrototypeOf;
f7eb47b… lmata 7 var __hasOwnProp = Object.prototype.hasOwnProperty;
f7eb47b… lmata 8 var __export = (target, all) => {
f7eb47b… lmata 9 for (var name in all)
f7eb47b… lmata 10 __defProp(target, name, { get: all[name], enumerable: true });
f7eb47b… lmata 11 };
f7eb47b… lmata 12 var __copyProps = (to, from, except, desc) => {
f7eb47b… lmata 13 if (from && typeof from === "object" || typeof from === "function") {
f7eb47b… lmata 14 for (let key of __getOwnPropNames(from))
f7eb47b… lmata 15 if (!__hasOwnProp.call(to, key) && key !== except)
f7eb47b… lmata 16 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
f7eb47b… lmata 17 }
f7eb47b… lmata 18 return to;
f7eb47b… lmata 19 };
f7eb47b… lmata 20 var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
f7eb47b… lmata 21 // If the importer is in node compatibility mode or this is not an ESM
f7eb47b… lmata 22 // file that has been converted to a CommonJS file using a Babel-
f7eb47b… lmata 23 // compatible transform (i.e. "__esModule" has not been set), then set
f7eb47b… lmata 24 // "default" to the CommonJS "module.exports" for node compatibility.
f7eb47b… lmata 25 isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
f7eb47b… lmata 26 mod
f7eb47b… lmata 27 ));
f7eb47b… lmata 28 var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
f7eb47b… lmata 29 var projectUtils_exports = {};
f7eb47b… lmata 30 __export(projectUtils_exports, {
f7eb47b… lmata 31 buildDependentProjects: () => buildDependentProjects,
f7eb47b… lmata 32 buildProjectsClosure: () => buildProjectsClosure,
f7eb47b… lmata 33 buildTeardownToSetupsMap: () => buildTeardownToSetupsMap,
f7eb47b… lmata 34 collectFilesForProject: () => collectFilesForProject,
f7eb47b… lmata 35 filterProjects: () => filterProjects,
f7eb47b… lmata 36 findTopLevelProjects: () => findTopLevelProjects
f7eb47b… lmata 37 });
f7eb47b… lmata 38 module.exports = __toCommonJS(projectUtils_exports);
f7eb47b… lmata 39 var import_fs = __toESM(require("fs"));
f7eb47b… lmata 40 var import_path = __toESM(require("path"));
f7eb47b… lmata 41 var import_util = require("util");
f7eb47b… lmata 42 var import_utils = require("playwright-core/lib/utils");
f7eb47b… lmata 43 var import_utilsBundle = require("playwright-core/lib/utilsBundle");
f7eb47b… lmata 44 var import_util2 = require("../util");
f7eb47b… lmata 45 const readFileAsync = (0, import_util.promisify)(import_fs.default.readFile);
f7eb47b… lmata 46 const readDirAsync = (0, import_util.promisify)(import_fs.default.readdir);
f7eb47b… lmata 47 function wildcardPatternToRegExp(pattern) {
f7eb47b… lmata 48 return new RegExp("^" + pattern.split("*").map(import_utils.escapeRegExp).join(".*") + "$", "ig");
f7eb47b… lmata 49 }
f7eb47b… lmata 50 function filterProjects(projects, projectNames) {
f7eb47b… lmata 51 if (!projectNames)
f7eb47b… lmata 52 return [...projects];
f7eb47b… lmata 53 const projectNamesToFind = /* @__PURE__ */ new Set();
f7eb47b… lmata 54 const unmatchedProjectNames = /* @__PURE__ */ new Map();
f7eb47b… lmata 55 const patterns = /* @__PURE__ */ new Set();
f7eb47b… lmata 56 for (const name of projectNames) {
f7eb47b… lmata 57 const lowerCaseName = name.toLocaleLowerCase();
f7eb47b… lmata 58 if (lowerCaseName.includes("*")) {
f7eb47b… lmata 59 patterns.add(wildcardPatternToRegExp(lowerCaseName));
f7eb47b… lmata 60 } else {
f7eb47b… lmata 61 projectNamesToFind.add(lowerCaseName);
f7eb47b… lmata 62 unmatchedProjectNames.set(lowerCaseName, name);
f7eb47b… lmata 63 }
f7eb47b… lmata 64 }
f7eb47b… lmata 65 const result = projects.filter((project) => {
f7eb47b… lmata 66 const lowerCaseName = project.project.name.toLocaleLowerCase();
f7eb47b… lmata 67 if (projectNamesToFind.has(lowerCaseName)) {
f7eb47b… lmata 68 unmatchedProjectNames.delete(lowerCaseName);
f7eb47b… lmata 69 return true;
f7eb47b… lmata 70 }
f7eb47b… lmata 71 for (const regex of patterns) {
f7eb47b… lmata 72 regex.lastIndex = 0;
f7eb47b… lmata 73 if (regex.test(lowerCaseName))
f7eb47b… lmata 74 return true;
f7eb47b… lmata 75 }
f7eb47b… lmata 76 return false;
f7eb47b… lmata 77 });
f7eb47b… lmata 78 if (unmatchedProjectNames.size) {
f7eb47b… lmata 79 const unknownProjectNames = Array.from(unmatchedProjectNames.values()).map((n) => `"${n}"`).join(", ");
f7eb47b… lmata 80 throw new Error(`Project(s) ${unknownProjectNames} not found. Available projects: ${projects.map((p) => `"${p.project.name}"`).join(", ")}`);
f7eb47b… lmata 81 }
f7eb47b… lmata 82 if (!result.length) {
f7eb47b… lmata 83 const allProjects = projects.map((p) => `"${p.project.name}"`).join(", ");
f7eb47b… lmata 84 throw new Error(`No projects matched. Available projects: ${allProjects}`);
f7eb47b… lmata 85 }
f7eb47b… lmata 86 return result;
f7eb47b… lmata 87 }
f7eb47b… lmata 88 function buildTeardownToSetupsMap(projects) {
f7eb47b… lmata 89 const result = /* @__PURE__ */ new Map();
f7eb47b… lmata 90 for (const project of projects) {
f7eb47b… lmata 91 if (project.teardown) {
f7eb47b… lmata 92 const setups = result.get(project.teardown) || [];
f7eb47b… lmata 93 setups.push(project);
f7eb47b… lmata 94 result.set(project.teardown, setups);
f7eb47b… lmata 95 }
f7eb47b… lmata 96 }
f7eb47b… lmata 97 return result;
f7eb47b… lmata 98 }
f7eb47b… lmata 99 function buildProjectsClosure(projects, hasTests) {
f7eb47b… lmata 100 const result = /* @__PURE__ */ new Map();
f7eb47b… lmata 101 const visit = (depth, project) => {
f7eb47b… lmata 102 if (depth > 100) {
f7eb47b… lmata 103 const error = new Error("Circular dependency detected between projects.");
f7eb47b… lmata 104 error.stack = "";
f7eb47b… lmata 105 throw error;
f7eb47b… lmata 106 }
f7eb47b… lmata 107 if (depth === 0 && hasTests && !hasTests(project))
f7eb47b… lmata 108 return;
f7eb47b… lmata 109 if (result.get(project) !== "dependency")
f7eb47b… lmata 110 result.set(project, depth ? "dependency" : "top-level");
f7eb47b… lmata 111 for (const dep of project.deps)
f7eb47b… lmata 112 visit(depth + 1, dep);
f7eb47b… lmata 113 if (project.teardown)
f7eb47b… lmata 114 visit(depth + 1, project.teardown);
f7eb47b… lmata 115 };
f7eb47b… lmata 116 for (const p of projects)
f7eb47b… lmata 117 visit(0, p);
f7eb47b… lmata 118 return result;
f7eb47b… lmata 119 }
f7eb47b… lmata 120 function findTopLevelProjects(config) {
f7eb47b… lmata 121 const closure = buildProjectsClosure(config.projects);
f7eb47b… lmata 122 return [...closure].filter((entry) => entry[1] === "top-level").map((entry) => entry[0]);
f7eb47b… lmata 123 }
f7eb47b… lmata 124 function buildDependentProjects(forProjects, projects) {
f7eb47b… lmata 125 const reverseDeps = new Map(projects.map((p) => [p, []]));
f7eb47b… lmata 126 for (const project of projects) {
f7eb47b… lmata 127 for (const dep of project.deps)
f7eb47b… lmata 128 reverseDeps.get(dep).push(project);
f7eb47b… lmata 129 }
f7eb47b… lmata 130 const result = /* @__PURE__ */ new Set();
f7eb47b… lmata 131 const visit = (depth, project) => {
f7eb47b… lmata 132 if (depth > 100) {
f7eb47b… lmata 133 const error = new Error("Circular dependency detected between projects.");
f7eb47b… lmata 134 error.stack = "";
f7eb47b… lmata 135 throw error;
f7eb47b… lmata 136 }
f7eb47b… lmata 137 result.add(project);
f7eb47b… lmata 138 for (const reverseDep of reverseDeps.get(project))
f7eb47b… lmata 139 visit(depth + 1, reverseDep);
f7eb47b… lmata 140 if (project.teardown)
f7eb47b… lmata 141 visit(depth + 1, project.teardown);
f7eb47b… lmata 142 };
f7eb47b… lmata 143 for (const forProject of forProjects)
f7eb47b… lmata 144 visit(0, forProject);
f7eb47b… lmata 145 return result;
f7eb47b… lmata 146 }
f7eb47b… lmata 147 async function collectFilesForProject(project, fsCache = /* @__PURE__ */ new Map()) {
f7eb47b… lmata 148 const extensions = /* @__PURE__ */ new Set([".js", ".ts", ".mjs", ".mts", ".cjs", ".cts", ".jsx", ".tsx", ".mjsx", ".mtsx", ".cjsx", ".ctsx", ".md"]);
f7eb47b… lmata 149 const testFileExtension = (file) => extensions.has(import_path.default.extname(file));
f7eb47b… lmata 150 const allFiles = await cachedCollectFiles(project.project.testDir, project.respectGitIgnore, fsCache);
f7eb47b… lmata 151 const testMatch = (0, import_util2.createFileMatcher)(project.project.testMatch);
f7eb47b… lmata 152 const testIgnore = (0, import_util2.createFileMatcher)(project.project.testIgnore);
f7eb47b… lmata 153 const testFiles = allFiles.filter((file) => {
f7eb47b… lmata 154 if (!testFileExtension(file))
f7eb47b… lmata 155 return false;
f7eb47b… lmata 156 const isTest = !testIgnore(file) && testMatch(file);
f7eb47b… lmata 157 if (!isTest)
f7eb47b… lmata 158 return false;
f7eb47b… lmata 159 return true;
f7eb47b… lmata 160 });
f7eb47b… lmata 161 return testFiles;
f7eb47b… lmata 162 }
f7eb47b… lmata 163 async function cachedCollectFiles(testDir, respectGitIgnore, fsCache) {
f7eb47b… lmata 164 const key = testDir + ":" + respectGitIgnore;
f7eb47b… lmata 165 let result = fsCache.get(key);
f7eb47b… lmata 166 if (!result) {
f7eb47b… lmata 167 result = await collectFiles(testDir, respectGitIgnore);
f7eb47b… lmata 168 fsCache.set(key, result);
f7eb47b… lmata 169 }
f7eb47b… lmata 170 return result;
f7eb47b… lmata 171 }
f7eb47b… lmata 172 async function collectFiles(testDir, respectGitIgnore) {
f7eb47b… lmata 173 if (!import_fs.default.existsSync(testDir))
f7eb47b… lmata 174 return [];
f7eb47b… lmata 175 if (!import_fs.default.statSync(testDir).isDirectory())
f7eb47b… lmata 176 return [];
f7eb47b… lmata 177 const checkIgnores = (entryPath, rules, isDirectory, parentStatus) => {
f7eb47b… lmata 178 let status = parentStatus;
f7eb47b… lmata 179 for (const rule of rules) {
f7eb47b… lmata 180 const ruleIncludes = rule.negate;
f7eb47b… lmata 181 if (status === "included" === ruleIncludes)
f7eb47b… lmata 182 continue;
f7eb47b… lmata 183 const relative = import_path.default.relative(rule.dir, entryPath);
f7eb47b… lmata 184 if (rule.match("/" + relative) || rule.match(relative)) {
f7eb47b… lmata 185 status = ruleIncludes ? "included" : "ignored";
f7eb47b… lmata 186 } else if (isDirectory && (rule.match("/" + relative + "/") || rule.match(relative + "/"))) {
f7eb47b… lmata 187 status = ruleIncludes ? "included" : "ignored";
f7eb47b… lmata 188 } else if (isDirectory && ruleIncludes && (rule.match("/" + relative, true) || rule.match(relative, true))) {
f7eb47b… lmata 189 status = "ignored-but-recurse";
f7eb47b… lmata 190 }
f7eb47b… lmata 191 }
f7eb47b… lmata 192 return status;
f7eb47b… lmata 193 };
f7eb47b… lmata 194 const files = [];
f7eb47b… lmata 195 const visit = async (dir, rules, status) => {
f7eb47b… lmata 196 const entries = await readDirAsync(dir, { withFileTypes: true });
f7eb47b… lmata 197 entries.sort((a, b) => a.name.localeCompare(b.name));
f7eb47b… lmata 198 if (respectGitIgnore) {
f7eb47b… lmata 199 const gitignore = entries.find((e) => e.isFile() && e.name === ".gitignore");
f7eb47b… lmata 200 if (gitignore) {
f7eb47b… lmata 201 const content = await readFileAsync(import_path.default.join(dir, gitignore.name), "utf8");
f7eb47b… lmata 202 const newRules = content.split(/\r?\n/).map((s) => {
f7eb47b… lmata 203 s = s.trim();
f7eb47b… lmata 204 if (!s)
f7eb47b… lmata 205 return;
f7eb47b… lmata 206 const rule = new import_utilsBundle.minimatch.Minimatch(s, { matchBase: true, dot: true, flipNegate: true });
f7eb47b… lmata 207 if (rule.comment)
f7eb47b… lmata 208 return;
f7eb47b… lmata 209 rule.dir = dir;
f7eb47b… lmata 210 return rule;
f7eb47b… lmata 211 }).filter((rule) => !!rule);
f7eb47b… lmata 212 rules = [...rules, ...newRules];
f7eb47b… lmata 213 }
f7eb47b… lmata 214 }
f7eb47b… lmata 215 for (const entry of entries) {
f7eb47b… lmata 216 if (entry.name === "." || entry.name === "..")
f7eb47b… lmata 217 continue;
f7eb47b… lmata 218 if (entry.isFile() && entry.name === ".gitignore")
f7eb47b… lmata 219 continue;
f7eb47b… lmata 220 if (entry.isDirectory() && entry.name === "node_modules")
f7eb47b… lmata 221 continue;
f7eb47b… lmata 222 const entryPath = import_path.default.join(dir, entry.name);
f7eb47b… lmata 223 const entryStatus = checkIgnores(entryPath, rules, entry.isDirectory(), status);
f7eb47b… lmata 224 if (entry.isDirectory() && entryStatus !== "ignored")
f7eb47b… lmata 225 await visit(entryPath, rules, entryStatus);
f7eb47b… lmata 226 else if (entry.isFile() && entryStatus === "included")
f7eb47b… lmata 227 files.push(entryPath);
f7eb47b… lmata 228 }
f7eb47b… lmata 229 };
f7eb47b… lmata 230 await visit(testDir, [], "included");
f7eb47b… lmata 231 return files;
f7eb47b… lmata 232 }
f7eb47b… lmata 233 // Annotate the CommonJS export names for ESM import in node:
f7eb47b… lmata 234 0 && (module.exports = {
f7eb47b… lmata 235 buildDependentProjects,
f7eb47b… lmata 236 buildProjectsClosure,
f7eb47b… lmata 237 buildTeardownToSetupsMap,
f7eb47b… lmata 238 collectFilesForProject,
f7eb47b… lmata 239 filterProjects,
f7eb47b… lmata 240 findTopLevelProjects
f7eb47b… lmata 241 });

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button