@testspectra/react 1.2.4 → 1.2.6
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.
- package/dist/index.js +98 -35
- package/dist/setup.js +33 -33
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -199,6 +199,18 @@ function mockResponseBodyText(body) {
|
|
|
199
199
|
function parseElementSentinel(selector) {
|
|
200
200
|
const closest = /^(.*)::closest\((.+)\)$/.exec(selector);
|
|
201
201
|
if (closest) return { kind: "closest", base: closest[1], arg: closest[2] };
|
|
202
|
+
const children = /^(.*)::children\((.*)\)$/.exec(selector);
|
|
203
|
+
if (children) return { kind: "children", base: children[1], arg: children[2].trim() || null };
|
|
204
|
+
const bareChildren = /^(.*)::children$/.exec(selector);
|
|
205
|
+
if (bareChildren) return { kind: "children", base: bareChildren[1], arg: null };
|
|
206
|
+
const siblings = /^(.*)::siblings\((.*)\)$/.exec(selector);
|
|
207
|
+
if (siblings) return { kind: "siblings", base: siblings[1], arg: siblings[2].trim() || null };
|
|
208
|
+
const bareSiblings = /^(.*)::siblings$/.exec(selector);
|
|
209
|
+
if (bareSiblings) return { kind: "siblings", base: bareSiblings[1], arg: null };
|
|
210
|
+
const next = /^(.*)::next\((.*)\)$/.exec(selector);
|
|
211
|
+
if (next) return { kind: "next", base: next[1], arg: next[2].trim() || null };
|
|
212
|
+
const bareNext = /^(.*)::next$/.exec(selector);
|
|
213
|
+
if (bareNext) return { kind: "next", base: bareNext[1], arg: null };
|
|
202
214
|
const parent = /^(.*)::parent$/.exec(selector);
|
|
203
215
|
if (parent) return { kind: "parent", base: parent[1] };
|
|
204
216
|
return null;
|
|
@@ -401,23 +413,50 @@ function resolveEl(selector, index) {
|
|
|
401
413
|
function selectorText(target) {
|
|
402
414
|
return typeof target === "string" ? target : target.selector;
|
|
403
415
|
}
|
|
404
|
-
function
|
|
416
|
+
function pickFromList(list, index) {
|
|
417
|
+
if (index === null || index === void 0) return list[0] ?? null;
|
|
418
|
+
if (index >= 0) return list[index] ?? null;
|
|
419
|
+
return list[list.length + index] ?? null;
|
|
420
|
+
}
|
|
421
|
+
function matchesSelector(el, selector) {
|
|
422
|
+
if (!selector) return true;
|
|
423
|
+
try {
|
|
424
|
+
return el.matches(selector);
|
|
425
|
+
} catch {
|
|
426
|
+
return false;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
function resolveSentinelList(raw, parent) {
|
|
405
430
|
const sentinel = parseElementSentinel(raw);
|
|
406
431
|
if (!sentinel) return void 0;
|
|
407
432
|
const baseTarget = parent ? { selector: sentinel.base, index: null, parent } : sentinel.base;
|
|
408
433
|
const base = resolveScopedEl(baseTarget, null);
|
|
409
|
-
if (
|
|
410
|
-
if (sentinel.kind === "
|
|
411
|
-
|
|
434
|
+
if (sentinel.kind === "parent") return base?.parentElement ? [base.parentElement] : [];
|
|
435
|
+
if (sentinel.kind === "closest") {
|
|
436
|
+
const ancestor = base?.closest(sentinel.arg) ?? null;
|
|
437
|
+
return ancestor ? [ancestor] : [];
|
|
438
|
+
}
|
|
439
|
+
if (!base) return [];
|
|
440
|
+
if (sentinel.kind === "children") {
|
|
441
|
+
return Array.from(base.children).filter((child) => matchesSelector(child, sentinel.arg));
|
|
442
|
+
}
|
|
443
|
+
if (sentinel.kind === "siblings") {
|
|
444
|
+
const parentEl = base.parentElement;
|
|
445
|
+
if (!parentEl) return [];
|
|
446
|
+
return Array.from(parentEl.children).filter((child) => child !== base && matchesSelector(child, sentinel.arg));
|
|
447
|
+
}
|
|
448
|
+
let sibling = base.nextElementSibling;
|
|
449
|
+
while (sibling && !matchesSelector(sibling, sentinel.arg)) sibling = sibling.nextElementSibling;
|
|
450
|
+
return sibling ? [sibling] : [];
|
|
412
451
|
}
|
|
413
452
|
function resolveScopedEl(target, fallbackIndex) {
|
|
414
453
|
if (typeof target === "string") {
|
|
415
|
-
const
|
|
416
|
-
if (
|
|
454
|
+
const sentinelList2 = resolveSentinelList(target, void 0);
|
|
455
|
+
if (sentinelList2 !== void 0) return pickFromList(sentinelList2, fallbackIndex);
|
|
417
456
|
return resolveEl(target, fallbackIndex);
|
|
418
457
|
}
|
|
419
|
-
const
|
|
420
|
-
if (
|
|
458
|
+
const sentinelList = resolveSentinelList(target.selector, target.parent);
|
|
459
|
+
if (sentinelList !== void 0) return pickFromList(sentinelList, target.index ?? fallbackIndex);
|
|
421
460
|
const parentEl = target.parent ? resolveScopedEl(target.parent, target.parent.index) : document.documentElement;
|
|
422
461
|
if (!parentEl) return null;
|
|
423
462
|
const css = resolveSelector(target.selector);
|
|
@@ -758,8 +797,12 @@ var DomDriverBridge = class {
|
|
|
758
797
|
}
|
|
759
798
|
async count(selector) {
|
|
760
799
|
if (typeof selector === "string") {
|
|
800
|
+
const sentinelList2 = resolveSentinelList(selector, void 0);
|
|
801
|
+
if (sentinelList2 !== void 0) return sentinelList2.length;
|
|
761
802
|
return document.querySelectorAll(resolveSelector(selector)).length;
|
|
762
803
|
}
|
|
804
|
+
const sentinelList = resolveSentinelList(selector.selector, selector.parent);
|
|
805
|
+
if (sentinelList !== void 0) return sentinelList.length;
|
|
763
806
|
const parentEl = selector.parent ? resolveScopedEl(selector.parent, selector.parent.index) : document.documentElement;
|
|
764
807
|
if (!parentEl) return 0;
|
|
765
808
|
return parentEl.querySelectorAll(resolveSelector(selector.selector)).length;
|
|
@@ -1206,34 +1249,53 @@ import * as esbuild from "esbuild";
|
|
|
1206
1249
|
import { createRequire as createRequire2 } from "node:module";
|
|
1207
1250
|
var bundleCache = /* @__PURE__ */ new Map();
|
|
1208
1251
|
var inFlightBuilds = /* @__PURE__ */ new Map();
|
|
1209
|
-
var
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
style.textContent = ${escaped};
|
|
1223
|
-
document.head.appendChild(style);
|
|
1224
|
-
}
|
|
1225
|
-
`,
|
|
1226
|
-
loader: "js"
|
|
1227
|
-
};
|
|
1228
|
-
} catch (e) {
|
|
1229
|
-
return {
|
|
1230
|
-
contents: `/* failed to load css: ${String(e)} */`,
|
|
1231
|
-
loader: "js"
|
|
1232
|
-
};
|
|
1233
|
-
}
|
|
1234
|
-
});
|
|
1252
|
+
var consumerRootForCss;
|
|
1253
|
+
var TAILWIND_CSS_HINT = /@import\s+['"]tailwindcss['"]|@tailwind\b|@source\b|@theme\b/;
|
|
1254
|
+
async function compileCss(raw, filePath) {
|
|
1255
|
+
const consumerRoot = consumerRootForCss;
|
|
1256
|
+
if (!consumerRoot || !TAILWIND_CSS_HINT.test(raw)) return raw;
|
|
1257
|
+
try {
|
|
1258
|
+
const req = createRequire2(path3.join(consumerRoot, "package.json"));
|
|
1259
|
+
const postcss = req("postcss");
|
|
1260
|
+
const tailwind = req("@tailwindcss/postcss");
|
|
1261
|
+
const result = await postcss([tailwind()]).process(raw, { from: filePath });
|
|
1262
|
+
return result.css;
|
|
1263
|
+
} catch {
|
|
1264
|
+
return raw;
|
|
1235
1265
|
}
|
|
1236
|
-
}
|
|
1266
|
+
}
|
|
1267
|
+
function createCssInjectorPlugin() {
|
|
1268
|
+
return {
|
|
1269
|
+
name: "spectra-css-injector",
|
|
1270
|
+
setup(build2) {
|
|
1271
|
+
build2.onLoad({ filter: /\.(css|scss|sass|less)$/ }, async (args) => {
|
|
1272
|
+
try {
|
|
1273
|
+
const raw = await fs.promises.readFile(args.path, "utf8");
|
|
1274
|
+
const css = await compileCss(raw, args.path);
|
|
1275
|
+
const escaped = JSON.stringify(css);
|
|
1276
|
+
const sourcePath = JSON.stringify(args.path);
|
|
1277
|
+
return {
|
|
1278
|
+
contents: `
|
|
1279
|
+
if (typeof document !== 'undefined') {
|
|
1280
|
+
const style = document.createElement('style');
|
|
1281
|
+
style.setAttribute('data-spectra-css', ${sourcePath});
|
|
1282
|
+
style.textContent = ${escaped};
|
|
1283
|
+
document.head.appendChild(style);
|
|
1284
|
+
}
|
|
1285
|
+
`,
|
|
1286
|
+
loader: "js"
|
|
1287
|
+
};
|
|
1288
|
+
} catch (e) {
|
|
1289
|
+
return {
|
|
1290
|
+
contents: `/* failed to load css: ${String(e)} */`,
|
|
1291
|
+
loader: "js"
|
|
1292
|
+
};
|
|
1293
|
+
}
|
|
1294
|
+
});
|
|
1295
|
+
}
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
var cssInjectorPlugin = createCssInjectorPlugin();
|
|
1237
1299
|
var SHARED_REACT_EXTERNALS = [
|
|
1238
1300
|
"react",
|
|
1239
1301
|
"react/jsx-runtime",
|
|
@@ -1575,6 +1637,7 @@ function makeHandler(testRoot, packageDir, harnessHtml, setupEntrypoint, runnerE
|
|
|
1575
1637
|
}
|
|
1576
1638
|
async function startBundleServer(opts = {}) {
|
|
1577
1639
|
const testRoot = path3.resolve(opts.testRoot ?? process.cwd());
|
|
1640
|
+
consumerRootForCss = testRoot;
|
|
1578
1641
|
const packageDir = opts.packageDir ?? resolveReactPackageDir();
|
|
1579
1642
|
const manifest = opts.manifest ?? { pageObjects: [], steps: [], fixtures: [] };
|
|
1580
1643
|
const stepDelayMs = opts.stepDelayMs ?? 0;
|