@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 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 resolveSentinel(raw, parent) {
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 (!base) return null;
410
- if (sentinel.kind === "parent") return base.parentElement ?? null;
411
- return base.closest(sentinel.arg) ?? null;
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 sentinel = resolveSentinel(target, void 0);
416
- if (sentinel !== void 0) return sentinel;
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 childSentinel = resolveSentinel(target.selector, target.parent);
420
- if (childSentinel !== void 0) return childSentinel;
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 cssInjectorPlugin = {
1210
- name: "spectra-css-injector",
1211
- setup(build2) {
1212
- build2.onLoad({ filter: /\.(css|scss|sass|less)$/ }, async (args) => {
1213
- try {
1214
- const raw = await fs.promises.readFile(args.path, "utf8");
1215
- const escaped = JSON.stringify(raw);
1216
- const sourcePath = JSON.stringify(args.path);
1217
- return {
1218
- contents: `
1219
- if (typeof document !== 'undefined') {
1220
- const style = document.createElement('style');
1221
- style.setAttribute('data-spectra-css', ${sourcePath});
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;