@piwitests/reporter 0.43.0 → 0.44.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.
Files changed (2) hide show
  1. package/dist/cli/index.js +74 -14
  2. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -1752,8 +1752,12 @@ function samePage(a, b) {
1752
1752
  const kb = pageKey(b);
1753
1753
  return ka === null || kb === null || ka === kb;
1754
1754
  }
1755
+ function viewportLine(viewport) {
1756
+ return ` await page.setViewportSize({ width: ${Math.round(viewport.width)}, height: ${Math.round(viewport.height)} });`;
1757
+ }
1755
1758
  function renderSpec(session, options = {}) {
1756
1759
  const { steps } = session;
1760
+ const viewportAt = new Map((session.viewports ?? []).map((v) => [v.step, v]));
1757
1761
  const title = options.title ?? "recorded flow";
1758
1762
  const catalog = (options.catalog ?? []).filter(callIdentifiersAreSafe);
1759
1763
  const ctx = {
@@ -1781,6 +1785,8 @@ function renderSpec(session, options = {}) {
1781
1785
  let sawGoto = false;
1782
1786
  while (pos < steps.length) {
1783
1787
  const step = steps[pos];
1788
+ const viewport = pos > 0 ? viewportAt.get(pos) : void 0;
1789
+ if (viewport) bodyLines.push(viewportLine(viewport));
1784
1790
  stepStarts[pos] = bodyLines.length;
1785
1791
  if (step.action === "goto") {
1786
1792
  bodyLines.push(...renderRawStep(step, pos, ctx));
@@ -1788,7 +1794,8 @@ function renderSpec(session, options = {}) {
1788
1794
  pos++;
1789
1795
  continue;
1790
1796
  }
1791
- const match = catalog.length > 0 ? matchFunctionAt(steps, pos, catalog) : null;
1797
+ const found = catalog.length > 0 ? matchFunctionAt(steps, pos, catalog) : null;
1798
+ const match = found && ![...viewportAt.keys()].some((at) => at > pos && at <= Math.max(...found.matchedIndices)) ? found : null;
1792
1799
  if (match) {
1793
1800
  bodyLines.push(renderFunctionCall(match));
1794
1801
  usedEntries.push(match.entry);
@@ -1803,11 +1810,13 @@ function renderSpec(session, options = {}) {
1803
1810
  checkNextPage(pos);
1804
1811
  pos++;
1805
1812
  }
1806
- let bodyOffset = 0;
1807
- if (!sawGoto && session.startUrl) {
1808
- bodyLines.unshift(` await page.goto(${quote2(urlForCode(session.startUrl, ctx))});`);
1809
- bodyOffset = 1;
1810
- }
1813
+ const start = viewportAt.get(0);
1814
+ const opening = [
1815
+ ...start ? [viewportLine(start)] : [],
1816
+ ...!sawGoto && session.startUrl ? [` await page.goto(${quote2(urlForCode(session.startUrl, ctx))});`] : []
1817
+ ];
1818
+ bodyLines.unshift(...opening);
1819
+ const bodyOffset = opening.length;
1811
1820
  const importLines = renderImports(usedEntries);
1812
1821
  const instantiationLines = renderInstantiations(usedEntries);
1813
1822
  const failLine = expectFailLine(options);
@@ -1825,7 +1834,7 @@ function renderSpec(session, options = {}) {
1825
1834
  };
1826
1835
  }
1827
1836
  const details = renderDetails(options);
1828
- const opening = details.length > 0 ? [`test(${quote2(title)}, {`, ...details, `}, async ({ page }) => {`] : [`test(${quote2(title)}, async ({ page }) => {`];
1837
+ const testOpening = details.length > 0 ? [`test(${quote2(title)}, {`, ...details, `}, async ({ page }) => {`] : [`test(${quote2(title)}, async ({ page }) => {`];
1829
1838
  const lines = [
1830
1839
  // Package name interpolated rather than adjoining the preceding keyword
1831
1840
  // directly, so this generated-code line does not itself look like a real
@@ -1833,12 +1842,12 @@ function renderSpec(session, options = {}) {
1833
1842
  `import { test, expect } from ${quote2(options.testImport?.trim() || "@playwright/test")};`,
1834
1843
  ...importLines,
1835
1844
  ``,
1836
- ...opening,
1845
+ ...testOpening,
1837
1846
  ...testBody,
1838
1847
  `});`,
1839
1848
  ``
1840
1849
  ];
1841
- const header = 1 + importLines.length + 1 + opening.length;
1850
+ const header = 1 + importLines.length + 1 + testOpening.length;
1842
1851
  return { code: lines.join("\n"), matchedSpans, warnings: ctx.warnings, stepLines: linesFrom(header) };
1843
1852
  }
1844
1853
 
@@ -1850,7 +1859,12 @@ var STEPS_LIMITS = {
1850
1859
  /** Typed values, expected values, URLs, notes. */
1851
1860
  valueLength: 2e3,
1852
1861
  /** Titles, names, texts, locators. */
1853
- textLength: 500
1862
+ textLength: 500,
1863
+ viewports: 50,
1864
+ /** The widest and tallest viewport, in CSS pixels. */
1865
+ viewportSize: 1e4,
1866
+ /** The browser's zoom factors a viewport may name, as browsers allow them. */
1867
+ zoom: { min: 0.25, max: 5 }
1854
1868
  };
1855
1869
  var ACTIONS = /* @__PURE__ */ new Set([
1856
1870
  "goto",
@@ -1895,13 +1909,14 @@ function toStepsDocument(session, meta = {}) {
1895
1909
  origin,
1896
1910
  recordedAt: session.startedAt,
1897
1911
  note: meta.note ?? null,
1898
- steps: session.steps.map((step) => ({
1912
+ steps: session.steps.map(({ view: _view, ...step }) => ({
1899
1913
  ...step,
1900
1914
  target: step.target ? withoutElementKey(step.target) : null,
1901
1915
  ...step.dropTarget ? { dropTarget: withoutElementKey(step.dropTarget) } : {},
1902
1916
  pageUrl: toPath(step.pageUrl, origin),
1903
1917
  value: step.action === "goto" && step.value ? toPath(step.value, origin) : step.value
1904
- }))
1918
+ })),
1919
+ ...session.viewports?.length ? { viewports: session.viewports.map((v) => ({ ...v })) } : {}
1905
1920
  };
1906
1921
  }
1907
1922
  function withoutElementKey(target) {
@@ -1915,7 +1930,12 @@ function sessionFromSteps(doc, origin = doc.origin) {
1915
1930
  value: step.action === "goto" && step.value ? toAbsolute(step.value, origin) : step.value
1916
1931
  }));
1917
1932
  const firstGoto = steps.find((s) => s.action === "goto");
1918
- return { steps, startedAt: doc.recordedAt, startUrl: firstGoto?.value ?? steps[0]?.pageUrl ?? origin ?? "" };
1933
+ return {
1934
+ steps,
1935
+ startedAt: doc.recordedAt,
1936
+ startUrl: firstGoto?.value ?? steps[0]?.pageUrl ?? origin ?? "",
1937
+ ...doc.viewports?.length ? { viewports: doc.viewports } : {}
1938
+ };
1919
1939
  }
1920
1940
  function isObject(v) {
1921
1941
  return typeof v === "object" && v !== null && !Array.isArray(v);
@@ -2001,6 +2021,44 @@ function checkAssertion(c, v, path19) {
2001
2021
  note: c.text(v.note, `${path19}.note`, STEPS_LIMITS.valueLength, true)
2002
2022
  };
2003
2023
  }
2024
+ function checkViewports(c, v, stepCount) {
2025
+ if (v == null) return [];
2026
+ if (!Array.isArray(v)) {
2027
+ c.fail("viewports", "must be a list");
2028
+ return [];
2029
+ }
2030
+ if (v.length > STEPS_LIMITS.viewports) {
2031
+ c.fail("viewports", `holds more than ${STEPS_LIMITS.viewports}`);
2032
+ return [];
2033
+ }
2034
+ const out = [];
2035
+ v.forEach((entry, i) => {
2036
+ const at = `viewports[${i}]`;
2037
+ if (!isObject(entry)) return c.fail(at, "must be an object");
2038
+ const { step, width, height } = entry;
2039
+ if (!Number.isInteger(step) || step < 0 || step >= stepCount)
2040
+ return c.fail(`${at}.step`, "must be the index of a step");
2041
+ for (const [name, size] of [
2042
+ ["width", width],
2043
+ ["height", height]
2044
+ ]) {
2045
+ if (!Number.isInteger(size) || size < 1 || size > STEPS_LIMITS.viewportSize)
2046
+ return c.fail(`${at}.${name}`, `must be a whole number of pixels from 1 to ${STEPS_LIMITS.viewportSize}`);
2047
+ }
2048
+ const { zoom } = entry;
2049
+ if (zoom != null && (typeof zoom !== "number" || !(zoom >= STEPS_LIMITS.zoom.min && zoom <= STEPS_LIMITS.zoom.max)))
2050
+ return c.fail(`${at}.zoom`, `must be a zoom factor from ${STEPS_LIMITS.zoom.min} to ${STEPS_LIMITS.zoom.max}`);
2051
+ const last = out[out.length - 1];
2052
+ if (last && last.step >= step) return c.fail(`${at}.step`, "must come after the step before it");
2053
+ out.push({
2054
+ step,
2055
+ width,
2056
+ height,
2057
+ ...zoom != null && zoom !== 1 ? { zoom } : {}
2058
+ });
2059
+ });
2060
+ return out;
2061
+ }
2004
2062
  function checkStep(c, v, path19) {
2005
2063
  if (!isObject(v)) {
2006
2064
  c.fail(path19, "must be an object");
@@ -2072,13 +2130,15 @@ function parseSteps(input) {
2072
2130
  const originText = c.text(value.origin, "origin", STEPS_LIMITS.textLength, true);
2073
2131
  const origin = originText ? originOf2(originText) : null;
2074
2132
  if (originText && !origin) c.fail("origin", "must be an http(s) origin");
2133
+ const viewports = checkViewports(c, value.viewports, steps.length);
2075
2134
  doc = {
2076
2135
  v: STEPS_VERSION,
2077
2136
  title: c.text(value.title, "title", STEPS_LIMITS.textLength, true),
2078
2137
  origin,
2079
2138
  recordedAt: value.recordedAt == null ? 0 : c.number(value.recordedAt, "recordedAt"),
2080
2139
  note: c.text(value.note, "note", STEPS_LIMITS.valueLength, true),
2081
- steps
2140
+ steps,
2141
+ ...viewports.length > 0 ? { viewports } : {}
2082
2142
  };
2083
2143
  }
2084
2144
  return c.errors.length > 0 ? { ok: false, errors: c.errors } : { ok: true, steps: doc };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@piwitests/reporter",
3
- "version": "0.43.0",
3
+ "version": "0.44.0",
4
4
  "description": "Playwright reporter that streams results, traces and HTML reports to a Piwi Dashboard instance",
5
5
  "url": "https://github.com/PiwiTests/platform",
6
6
  "homepage": "https://piwitests.dev",