@aplaytest/report 0.1.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
+ {"fileNames":["../../../node_modules/typescript/lib/lib.es5.d.ts","../../../node_modules/typescript/lib/lib.es2015.d.ts","../../../node_modules/typescript/lib/lib.es2016.d.ts","../../../node_modules/typescript/lib/lib.es2017.d.ts","../../../node_modules/typescript/lib/lib.es2018.d.ts","../../../node_modules/typescript/lib/lib.es2019.d.ts","../../../node_modules/typescript/lib/lib.es2020.d.ts","../../../node_modules/typescript/lib/lib.es2021.d.ts","../../../node_modules/typescript/lib/lib.es2022.d.ts","../../../node_modules/typescript/lib/lib.es2023.d.ts","../../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../../node_modules/typescript/lib/lib.es2016.intl.d.ts","../../../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../../node_modules/typescript/lib/lib.es2017.date.d.ts","../../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../../node_modules/typescript/lib/lib.es2021.promise.d.ts","../../../node_modules/typescript/lib/lib.es2021.string.d.ts","../../../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../../node_modules/typescript/lib/lib.es2021.intl.d.ts","../../../node_modules/typescript/lib/lib.es2022.array.d.ts","../../../node_modules/typescript/lib/lib.es2022.error.d.ts","../../../node_modules/typescript/lib/lib.es2022.intl.d.ts","../../../node_modules/typescript/lib/lib.es2022.object.d.ts","../../../node_modules/typescript/lib/lib.es2022.string.d.ts","../../../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../../node_modules/typescript/lib/lib.es2023.array.d.ts","../../../node_modules/typescript/lib/lib.es2023.collection.d.ts","../../../node_modules/typescript/lib/lib.es2023.intl.d.ts","../../../node_modules/typescript/lib/lib.decorators.d.ts","../../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../src/args.ts","../../core/dist/taxonomy/kinds.d.ts","../../core/dist/locator/stability.d.ts","../../core/dist/evidence/types.d.ts","../../core/dist/taxonomy/classify.d.ts","../../core/dist/taxonomy/parse-error.d.ts","../../core/dist/version.d.ts","../../core/dist/evidence/id.d.ts","../../core/dist/evidence/redact.d.ts","../../core/dist/evidence/store.d.ts","../../core/dist/history/types.d.ts","../../core/dist/history/store.d.ts","../../core/dist/history/memory-index.d.ts","../../core/dist/history/url.d.ts","../../core/dist/history/ingest.d.ts","../../core/dist/history/playwright-report.d.ts","../../core/dist/history/ingest-playwright.d.ts","../../../node_modules/zod/v4/core/json-schema.d.cts","../../../node_modules/zod/v4/core/standard-schema.d.cts","../../../node_modules/zod/v4/core/registries.d.cts","../../../node_modules/zod/v4/core/to-json-schema.d.cts","../../../node_modules/zod/v4/core/util.d.cts","../../../node_modules/zod/v4/core/versions.d.cts","../../../node_modules/zod/v4/core/schemas.d.cts","../../../node_modules/zod/v4/core/checks.d.cts","../../../node_modules/zod/v4/core/errors.d.cts","../../../node_modules/zod/v4/core/core.d.cts","../../../node_modules/zod/v4/core/parse.d.cts","../../../node_modules/zod/v4/core/regexes.d.cts","../../../node_modules/zod/v4/locales/ar.d.cts","../../../node_modules/zod/v4/locales/az.d.cts","../../../node_modules/zod/v4/locales/be.d.cts","../../../node_modules/zod/v4/locales/bg.d.cts","../../../node_modules/zod/v4/locales/ca.d.cts","../../../node_modules/zod/v4/locales/cs.d.cts","../../../node_modules/zod/v4/locales/da.d.cts","../../../node_modules/zod/v4/locales/de.d.cts","../../../node_modules/zod/v4/locales/el.d.cts","../../../node_modules/zod/v4/locales/en.d.cts","../../../node_modules/zod/v4/locales/eo.d.cts","../../../node_modules/zod/v4/locales/es.d.cts","../../../node_modules/zod/v4/locales/fa.d.cts","../../../node_modules/zod/v4/locales/fi.d.cts","../../../node_modules/zod/v4/locales/fr.d.cts","../../../node_modules/zod/v4/locales/fr-CA.d.cts","../../../node_modules/zod/v4/locales/he.d.cts","../../../node_modules/zod/v4/locales/hr.d.cts","../../../node_modules/zod/v4/locales/hu.d.cts","../../../node_modules/zod/v4/locales/hy.d.cts","../../../node_modules/zod/v4/locales/id.d.cts","../../../node_modules/zod/v4/locales/is.d.cts","../../../node_modules/zod/v4/locales/it.d.cts","../../../node_modules/zod/v4/locales/ja.d.cts","../../../node_modules/zod/v4/locales/ka.d.cts","../../../node_modules/zod/v4/locales/kh.d.cts","../../../node_modules/zod/v4/locales/km.d.cts","../../../node_modules/zod/v4/locales/ko.d.cts","../../../node_modules/zod/v4/locales/lt.d.cts","../../../node_modules/zod/v4/locales/mk.d.cts","../../../node_modules/zod/v4/locales/ms.d.cts","../../../node_modules/zod/v4/locales/nl.d.cts","../../../node_modules/zod/v4/locales/no.d.cts","../../../node_modules/zod/v4/locales/ota.d.cts","../../../node_modules/zod/v4/locales/ps.d.cts","../../../node_modules/zod/v4/locales/pl.d.cts","../../../node_modules/zod/v4/locales/pt.d.cts","../../../node_modules/zod/v4/locales/ro.d.cts","../../../node_modules/zod/v4/locales/ru.d.cts","../../../node_modules/zod/v4/locales/sl.d.cts","../../../node_modules/zod/v4/locales/sv.d.cts","../../../node_modules/zod/v4/locales/ta.d.cts","../../../node_modules/zod/v4/locales/th.d.cts","../../../node_modules/zod/v4/locales/tr.d.cts","../../../node_modules/zod/v4/locales/ua.d.cts","../../../node_modules/zod/v4/locales/uk.d.cts","../../../node_modules/zod/v4/locales/ur.d.cts","../../../node_modules/zod/v4/locales/uz.d.cts","../../../node_modules/zod/v4/locales/vi.d.cts","../../../node_modules/zod/v4/locales/zh-CN.d.cts","../../../node_modules/zod/v4/locales/zh-TW.d.cts","../../../node_modules/zod/v4/locales/yo.d.cts","../../../node_modules/zod/v4/locales/index.d.cts","../../../node_modules/zod/v4/core/doc.d.cts","../../../node_modules/zod/v4/core/api.d.cts","../../../node_modules/zod/v4/core/json-schema-processors.d.cts","../../../node_modules/zod/v4/core/json-schema-generator.d.cts","../../../node_modules/zod/v4/core/index.d.cts","../../../node_modules/zod/v4/classic/errors.d.cts","../../../node_modules/zod/v4/classic/parse.d.cts","../../../node_modules/zod/v4/classic/schemas.d.cts","../../../node_modules/zod/v4/classic/checks.d.cts","../../../node_modules/zod/v4/classic/compat.d.cts","../../../node_modules/zod/v4/classic/from-json-schema.d.cts","../../../node_modules/zod/v4/classic/iso.d.cts","../../../node_modules/zod/v4/classic/coerce.d.cts","../../../node_modules/zod/v4/classic/external.d.cts","../../../node_modules/zod/index.d.cts","../../core/dist/config/schema.d.ts","../../core/dist/index.d.ts","../src/merge.ts","../src/markdown.ts","../src/html.ts","../src/load.ts","../src/index.ts","../../../node_modules/@types/deep-eql/index.d.ts","../../../node_modules/assertion-error/index.d.ts","../../../node_modules/@types/chai/index.d.ts","../../../node_modules/@types/node/compatibility/disposable.d.ts","../../../node_modules/@types/node/compatibility/indexable.d.ts","../../../node_modules/@types/node/compatibility/iterators.d.ts","../../../node_modules/@types/node/compatibility/index.d.ts","../../../node_modules/@types/node/globals.typedarray.d.ts","../../../node_modules/@types/node/buffer.buffer.d.ts","../../../node_modules/@types/node/globals.d.ts","../../../node_modules/@types/node/web-globals/abortcontroller.d.ts","../../../node_modules/@types/node/web-globals/domexception.d.ts","../../../node_modules/@types/node/web-globals/events.d.ts","../../../node_modules/buffer/index.d.ts","../../../node_modules/undici-types/header.d.ts","../../../node_modules/undici-types/readable.d.ts","../../../node_modules/undici-types/file.d.ts","../../../node_modules/undici-types/fetch.d.ts","../../../node_modules/undici-types/formdata.d.ts","../../../node_modules/undici-types/connector.d.ts","../../../node_modules/undici-types/client.d.ts","../../../node_modules/undici-types/errors.d.ts","../../../node_modules/undici-types/dispatcher.d.ts","../../../node_modules/undici-types/global-dispatcher.d.ts","../../../node_modules/undici-types/global-origin.d.ts","../../../node_modules/undici-types/pool-stats.d.ts","../../../node_modules/undici-types/pool.d.ts","../../../node_modules/undici-types/handlers.d.ts","../../../node_modules/undici-types/balanced-pool.d.ts","../../../node_modules/undici-types/agent.d.ts","../../../node_modules/undici-types/mock-interceptor.d.ts","../../../node_modules/undici-types/mock-agent.d.ts","../../../node_modules/undici-types/mock-client.d.ts","../../../node_modules/undici-types/mock-pool.d.ts","../../../node_modules/undici-types/mock-errors.d.ts","../../../node_modules/undici-types/proxy-agent.d.ts","../../../node_modules/undici-types/env-http-proxy-agent.d.ts","../../../node_modules/undici-types/retry-handler.d.ts","../../../node_modules/undici-types/retry-agent.d.ts","../../../node_modules/undici-types/api.d.ts","../../../node_modules/undici-types/interceptors.d.ts","../../../node_modules/undici-types/util.d.ts","../../../node_modules/undici-types/cookies.d.ts","../../../node_modules/undici-types/patch.d.ts","../../../node_modules/undici-types/websocket.d.ts","../../../node_modules/undici-types/eventsource.d.ts","../../../node_modules/undici-types/filereader.d.ts","../../../node_modules/undici-types/diagnostics-channel.d.ts","../../../node_modules/undici-types/content-type.d.ts","../../../node_modules/undici-types/cache.d.ts","../../../node_modules/undici-types/index.d.ts","../../../node_modules/@types/node/web-globals/fetch.d.ts","../../../node_modules/@types/node/web-globals/navigator.d.ts","../../../node_modules/@types/node/web-globals/storage.d.ts","../../../node_modules/@types/node/web-globals/streams.d.ts","../../../node_modules/@types/node/assert.d.ts","../../../node_modules/@types/node/assert/strict.d.ts","../../../node_modules/@types/node/async_hooks.d.ts","../../../node_modules/@types/node/buffer.d.ts","../../../node_modules/@types/node/child_process.d.ts","../../../node_modules/@types/node/cluster.d.ts","../../../node_modules/@types/node/console.d.ts","../../../node_modules/@types/node/constants.d.ts","../../../node_modules/@types/node/crypto.d.ts","../../../node_modules/@types/node/dgram.d.ts","../../../node_modules/@types/node/diagnostics_channel.d.ts","../../../node_modules/@types/node/dns.d.ts","../../../node_modules/@types/node/dns/promises.d.ts","../../../node_modules/@types/node/domain.d.ts","../../../node_modules/@types/node/events.d.ts","../../../node_modules/@types/node/fs.d.ts","../../../node_modules/@types/node/fs/promises.d.ts","../../../node_modules/@types/node/http.d.ts","../../../node_modules/@types/node/http2.d.ts","../../../node_modules/@types/node/https.d.ts","../../../node_modules/@types/node/inspector.d.ts","../../../node_modules/@types/node/inspector.generated.d.ts","../../../node_modules/@types/node/module.d.ts","../../../node_modules/@types/node/net.d.ts","../../../node_modules/@types/node/os.d.ts","../../../node_modules/@types/node/path.d.ts","../../../node_modules/@types/node/perf_hooks.d.ts","../../../node_modules/@types/node/process.d.ts","../../../node_modules/@types/node/punycode.d.ts","../../../node_modules/@types/node/querystring.d.ts","../../../node_modules/@types/node/readline.d.ts","../../../node_modules/@types/node/readline/promises.d.ts","../../../node_modules/@types/node/repl.d.ts","../../../node_modules/@types/node/sea.d.ts","../../../node_modules/@types/node/sqlite.d.ts","../../../node_modules/@types/node/stream.d.ts","../../../node_modules/@types/node/stream/promises.d.ts","../../../node_modules/@types/node/stream/consumers.d.ts","../../../node_modules/@types/node/stream/web.d.ts","../../../node_modules/@types/node/string_decoder.d.ts","../../../node_modules/@types/node/test.d.ts","../../../node_modules/@types/node/timers.d.ts","../../../node_modules/@types/node/timers/promises.d.ts","../../../node_modules/@types/node/tls.d.ts","../../../node_modules/@types/node/trace_events.d.ts","../../../node_modules/@types/node/tty.d.ts","../../../node_modules/@types/node/url.d.ts","../../../node_modules/@types/node/util.d.ts","../../../node_modules/@types/node/v8.d.ts","../../../node_modules/@types/node/vm.d.ts","../../../node_modules/@types/node/wasi.d.ts","../../../node_modules/@types/node/worker_threads.d.ts","../../../node_modules/@types/node/zlib.d.ts","../../../node_modules/@types/node/index.d.ts","../../../node_modules/@types/ssh2/index.d.ts","../../../node_modules/@types/docker-modem/index.d.ts","../../../node_modules/@types/dockerode/index.d.ts","../../../node_modules/@types/estree/index.d.ts","../../../node_modules/@types/ssh2-streams/index.d.ts"],"fileIdsList":[[166,167,174,224,241,242],[174,224,241,242],[174,224,238,241,242,244,256,274,275],[174,224,235,241,242,256,274,275,276],[174,221,222,224,241,242],[174,223,224,241,242],[224,241,242],[174,224,229,241,242,259],[174,224,225,230,235,241,242,244,256,267],[174,224,225,226,235,241,242,244],[169,170,171,174,224,241,242],[174,224,227,241,242,268],[174,224,228,229,236,241,242,245],[174,224,229,241,242,256,264],[174,224,230,232,235,241,242,244],[174,223,224,231,241,242],[174,224,232,233,241,242],[174,224,234,235,241,242],[174,223,224,235,241,242],[174,224,235,236,237,241,242,256,267],[174,224,235,236,237,241,242,251,256,259],[174,216,224,232,235,238,241,242,244,256,267],[174,224,235,236,238,239,241,242,244,256,264,267],[174,224,238,240,241,242,256,264,267],[172,173,174,175,176,177,178,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273],[174,224,235,241,242],[174,224,241,242,243,267],[174,224,232,235,241,242,244,256],[174,224,241,242,245],[174,224,241,242,246],[174,223,224,241,242,247],[174,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273],[174,224,241,242,249],[174,224,241,242,250],[174,224,235,241,242,251,252],[174,224,241,242,251,253,268,270],[174,224,236,241,242],[174,224,235,241,242,256,257,259],[174,224,241,242,258,259],[174,224,241,242,256,257],[174,224,241,242,259],[174,224,241,242,260],[174,221,224,241,242,256,261,267],[174,224,235,241,242,262,263],[174,224,241,242,262,263],[174,224,229,241,242,244,256,264],[174,224,241,242,265],[174,224,241,242,244,266],[174,224,238,241,242,250,267],[174,224,229,241,242,268],[174,224,241,242,256,269],[174,224,241,242,243,270],[174,224,241,242,271],[174,216,224,241,242],[174,216,224,235,237,241,242,247,256,259,267,269,270,272],[174,224,241,242,256,273],[174,224,241,242,256,274],[174,224,235,238,240,241,242,244,256,274],[174,188,192,224,241,242,267],[174,188,224,241,242,256,267],[174,183,224,241,242],[174,185,188,224,241,242,264,267],[174,224,241,242,244,264],[174,224,241,242,274],[174,183,224,241,242,274],[174,185,188,224,241,242,244,267],[174,180,181,184,187,224,235,241,242,256,267],[174,188,195,224,241,242],[174,180,186,224,241,242],[174,188,209,210,224,241,242],[174,184,188,224,241,242,259,267,274],[174,209,224,241,242,274],[174,182,183,224,241,242,274],[174,188,224,241,242],[174,182,183,184,185,186,187,188,189,190,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,210,211,212,213,214,215,224,241,242],[174,188,203,224,241,242],[174,188,195,196,224,241,242],[174,186,188,196,197,224,241,242],[174,187,224,241,242],[174,180,183,188,224,241,242],[174,188,192,196,197,224,241,242],[174,192,224,241,242],[174,186,188,191,224,241,242,267],[174,180,185,188,195,224,241,242],[174,224,241,242,256],[174,183,188,209,224,241,242,272,274],[157,174,224,241,242],[148,174,224,241,242],[148,151,174,224,241,242],[83,143,146,148,149,150,151,152,153,154,155,156,174,224,241,242],[79,81,151,174,224,241,242],[148,149,174,224,241,242],[80,148,150,174,224,241,242],[81,83,85,86,87,88,174,224,241,242],[83,85,87,88,174,224,241,242],[83,85,87,174,224,241,242],[80,83,85,86,88,174,224,241,242],[79,81,82,83,84,85,86,87,88,89,90,143,144,145,146,147,174,224,241,242],[79,81,82,85,174,224,241,242],[81,82,85,174,224,241,242],[85,88,174,224,241,242],[79,80,82,83,84,86,87,88,174,224,241,242],[79,80,81,85,148,174,224,241,242],[85,86,87,88,174,224,241,242],[87,174,224,241,242],[91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,174,224,241,242],[158,174,224,241,242],[65,174,224,241,242],[63,64,174,224,241,242],[73,76,77,174,224,241,242],[73,174,224,241,242],[72,73,174,224,241,242],[72,174,224,241,242],[63,65,174,224,241,242],[63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,159,174,224,241,242],[62,160,161,162,174,224,241,242],[62,161,162,163,164,174,224,241,242],[160,174,224,237,241,242,246],[62,160,161,174,224,241,242],[160,174,224,241,242]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"df83c2a6c73228b625b0beb6669c7ee2a09c914637e2d35170723ad49c0f5cd4","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"ccee541ba11f0f699e0dd6d8795bd371721fb71e4be0bcad52848a7c0da88940","signature":"dd9e849078e26dcbc5d78f34a7da643a09f2d0544e806e602ba529a4ca4783f3","impliedFormat":99},{"version":"717f3d25205cb7aa457015fff8e21404fd000c53d65ebdbdedb51357c0ebe7e4","impliedFormat":99},{"version":"3a1521b2fd53734414b37c13230f2b50fbb8abb7e5a7e2d0088ae9c5adcedefd","impliedFormat":99},{"version":"f307dd9e98c0dd2eac07116cbff921047ce37ce578ffbdd2ceb24d6944341f58","impliedFormat":99},{"version":"6a07000e612ab26985fd379c93208a064e3ce4e87d109b49104b8f9ed2931268","impliedFormat":99},{"version":"c797dcf68a38d70efcfd0717e1cde4ceebb80c652d2630460f538e51a5e995f6","impliedFormat":99},{"version":"3c3bddc6344d4d31d83571cfbc0a0a43fefe8f2d863f1bf2bb738c12d73a5b96","impliedFormat":99},{"version":"187a77c78a8fb3c12cb0706c78c4986518527593a6fed4a516d1b18fcf283004","impliedFormat":99},{"version":"3c211d80f5b7543fdfa63b0962082b694bae2c00825314a19666af3d4ec60bed","impliedFormat":99},{"version":"6823183be31f0db3e2ed971e7b1c618bb681e5a83533ab026ea4b1a21575fdb4","impliedFormat":99},{"version":"d509894f9ecc0ca841c5f8fd269a4fe82f52323b8e016d07a1c593222905b3ee","impliedFormat":99},{"version":"933d85a3c2a78c17a493a0bd5fbe7065ce01f24c2f785b52792b178deb668210","impliedFormat":99},{"version":"81bdeb68b2554c68839b880d88bcbe2648edb81d8369c3b17ad22209a1ea8fe8","impliedFormat":99},{"version":"6bda8e7bd000605c09dd921fbcda240fee8121ba366c506956fcce546b1b7899","impliedFormat":99},{"version":"f17c6226d5e20284d8fdb567969ab21f08c0f4dd8492c13b952419f79c7ee43d","impliedFormat":99},{"version":"c52515057d9eab723b77cc3fa0cbd4fb1548fe0f5f03dd53f9f1ed871beb108b","impliedFormat":99},{"version":"b508da1c92e3d669855527d2e4dcf2ca266b9e192b3c5df2fa50f03a39159092","impliedFormat":99},{"version":"c1a2e05eb6d7ca8d7e4a7f4c93ccf0c2857e842a64c98eaee4d85841ee9855e6","impliedFormat":1},{"version":"835fb2909ce458740fb4a49fc61709896c6864f5ce3db7f0a88f06c720d74d02","impliedFormat":1},{"version":"6e5857f38aa297a859cab4ec891408659218a5a2610cd317b6dcbef9979459cc","impliedFormat":1},{"version":"ead8e39c2e11891f286b06ae2aa71f208b1802661fcdb2425cffa4f494a68854","impliedFormat":1},{"version":"40ba6c32eb732a09e4446ade5cb6ad0c147f186f9c9dc6878b90b4418ad9f6ea","impliedFormat":1},{"version":"fdd814741843f85c98281522c58f5a646590ba9019fad2efaa95987655e0611b","impliedFormat":1},{"version":"c78aff4fb58b28b8f642d5095fc7eeb79f00e652a67caa19693af1adabb833c9","impliedFormat":1},{"version":"f80a08ced8818dc99359c0acd5b3f12762e1ce53758007759b0d4e503cbf4a5e","impliedFormat":1},{"version":"37935fa7564bcc6e0bc845b766a24391098d26f7c8245d6e8ab37bc016816e94","impliedFormat":1},{"version":"68add36d9632bc096d7245d24d6b0b8ad5f125183016102a3dad4c9c2438ccb0","impliedFormat":1},{"version":"3a819c2928ee06bbcc84e2797fd3558ae2ebb7e0ed8d87f71732fb2e2acc87b4","impliedFormat":1},{"version":"0f8a263f4c8595c8a07de52e3f3927640c44386c1aa2984de9eae50d75e613b2","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"e0bfe601a9fdf6defe94ed62dc60ac71597566001a1f86e705c95e431a9c816d","impliedFormat":1},{"version":"346fffde7c32da87c2196eb7494422449dc2ca82d3b4e6bf55be1d1a33ffc2b0","impliedFormat":1},{"version":"add0ce7b77ba5b308492fa68f77f24d1ed1d9148534bdf05ac17c30763fc1a79","impliedFormat":1},{"version":"8b5875e4958528042103fdd775e106a7f76bafc29709f0690df9a7d2241d52a7","impliedFormat":1},{"version":"2f67911e4bf4e0717dc2ded248ce2d5e4398d945ee13889a6852c1233ea41508","impliedFormat":1},{"version":"d8430c275b0f59417ea8e173cfb888a4477b430ec35b595bf734f3ec7a7d729f","impliedFormat":1},{"version":"69364df1c776372d7df1fb46a6cb3a6bf7f55e700f533a104e3f9d70a32bec18","impliedFormat":1},{"version":"6042774c61ece4ba77b3bf375f15942eb054675b7957882a00c22c0e4fe5865c","impliedFormat":1},{"version":"5a3bd57ed7a9d9afef74c75f77fce79ba3c786401af9810cdf45907c4e93f30e","impliedFormat":1},{"version":"aef26cf95593c8ace1c62c4724f9afac77bdfa756fb8a00613cd152117cb2f43","impliedFormat":1},{"version":"30db853bb2e60170ba11e39ab48bacecb32d06d4def89eedf17e58ebab762a65","impliedFormat":1},{"version":"e27451b24234dfed45f6cf22112a04955183a99c42a2691fb4936d63cfe42761","impliedFormat":1},{"version":"2316301dd223d31962d917999acf8e543e0119c5d24ec984c9f22cb23247160c","impliedFormat":1},{"version":"58d65a2803c3b6629b0e18c8bf1bc883a686fcf0333230dd0151ab6e85b74307","impliedFormat":1},{"version":"e818471014c77c103330aee11f00a7a00b37b35500b53ea6f337aefacd6174c9","impliedFormat":1},{"version":"268fd6d9f2e807a39a6c5aa654b00f949feb63d3faa7dd0f9bba7dde9172159c","impliedFormat":1},{"version":"29f823cbe0166e10e7176a94afe609a24b9e5af3858628c541ff8ce1727023cd","impliedFormat":1},{"version":"23b7719fd261ad7f952ba1de0bca96bf9f98e8277715a4e85c411c1aab9d6410","impliedFormat":99},{"version":"f6804919eefe16c55372d52c152cbcf64ead302377193dd825e21bf5bb1a8eb0","impliedFormat":99},{"version":"55abf32fd3cc8f12d2bb803472ee17c999606278684b13a3dee4300cafced16c","signature":"313ea27cc8f967e9857a53b947d173cccd8337d5a3915ae08554f4a81b5b5f99","impliedFormat":99},{"version":"0ce8f5e6da2c0209b3010b882b4b14ddb9e999831608156ecaa2fdfe6e735935","signature":"b9bbc3778d2a74a718e13ee5f606c79f5bdae6edddb4a16a274fcbe9745fa726","impliedFormat":99},{"version":"176af2e112a6c0f7675fc111f0164f3f99f96f0cf7667dc64c2ead1cc4cfe978","signature":"9e61b2de2c9c2ba234c11eee1681da05115901bde9654e129bb678898e9a780d","impliedFormat":99},{"version":"7b204d1d40a89c6bfd4664e980f8e70555f0d3d5cd34d8488f8ad183fec884d9","signature":"4035d55351168ad52dd70ca4ce03f4b1082e39d4797d983823a5d71b410271fc","impliedFormat":99},{"version":"9672aef09430228996f445476c3d02c7c728eac25d09c4d3264f9441a3608dbb","signature":"fcccd699c361201c8c9253610597135086f14ad076a0b5bcc97b36d5ef9b6fba","impliedFormat":99},{"version":"427fe2004642504828c1476d0af4270e6ad4db6de78c0b5da3e4c5ca95052a99","impliedFormat":1},{"version":"2eeffcee5c1661ddca53353929558037b8cf305ffb86a803512982f99bcab50d","impliedFormat":99},{"version":"9afb4cb864d297e4092a79ee2871b5d3143ea14153f62ef0bb04ede25f432030","affectsGlobalScope":true,"impliedFormat":99},{"version":"6c7176368037af28cb72f2392010fa1cef295d6d6744bca8cfb54985f3a18c3e","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"437e20f2ba32abaeb7985e0afe0002de1917bc74e949ba585e49feba65da6ca1","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"98cffbf06d6bab333473c70a893770dbe990783904002c4f1a960447b4b53dca","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"808069bba06b6768b62fd22429b53362e7af342da4a236ed2d2e1c89fcca3b4a","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"4967529644e391115ca5592184d4b63980569adf60ee685f968fd59ab1557188","impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"b52476feb4a0cbcb25e5931b930fc73cb6643fb1a5060bf8a3dda0eeae5b4b68","affectsGlobalScope":true,"impliedFormat":1},{"version":"f9501cc13ce624c72b61f12b3963e84fad210fbdf0ffbc4590e08460a3f04eba","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d97fb21da858fb18b8ae72c314e9743fd52f73ebe2764e12af1db32fc03f853f","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fa06ada475b910e2106c98c68b10483dc8811d0c14a8a8dd36efb2672485b29","impliedFormat":1},{"version":"33e5e9aba62c3193d10d1d33ae1fa75c46a1171cf76fef750777377d53b0303f","impliedFormat":1},{"version":"2b06b93fd01bcd49d1a6bd1f9b65ddcae6480b9a86e9061634d6f8e354c1468f","impliedFormat":1},{"version":"6a0cd27e5dc2cfbe039e731cf879d12b0e2dded06d1b1dedad07f7712de0d7f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"13f5c844119c43e51ce777c509267f14d6aaf31eafb2c2b002ca35584cd13b29","impliedFormat":1},{"version":"e60477649d6ad21542bd2dc7e3d9ff6853d0797ba9f689ba2f6653818999c264","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"4c829ab315f57c5442c6667b53769975acbf92003a66aef19bce151987675bd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"b2ade7657e2db96d18315694789eff2ddd3d8aea7215b181f8a0b303277cc579","impliedFormat":1},{"version":"78dbea00e90d2df8ea3dbef0cc379d95b8be9b71cd6bde4c28728f306811803b","impliedFormat":1},{"version":"4d631b81fa2f07a0e63a9a143d6a82c25c5f051298651a9b69176ba28930756d","impliedFormat":1},{"version":"836a356aae992ff3c28a0212e3eabcb76dd4b0cc06bcb9607aeef560661b860d","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"41670ee38943d9cbb4924e436f56fc19ee94232bc96108562de1a734af20dc2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e1e46d0a9837ee058c100501080c920fa98081ea3956af0374308ba6f22a33e","impliedFormat":1},{"version":"272ca407e0c9068bdc5152552d876e68037ceae3de62e529306403e973dec8e1","impliedFormat":1},{"version":"fa7834c715d5357e4540cee40ce96c3250ddb67a7b879a6b7fa0e86d6696f121","impliedFormat":1},{"version":"22dfb07a7ab15b66ac043829056fe70124844636ae719551812ac631ba04985b","impliedFormat":1},{"version":"a10f0e1854f3316d7ee437b79649e5a6ae3ae14ffe6322b02d4987071a95362e","impliedFormat":1},{"version":"e208f73ef6a980104304b0d2ca5f6bf1b85de6009d2c7e404028b875020fa8f2","impliedFormat":1},{"version":"d163b6bc2372b4f07260747cbc6c0a6405ab3fbcea3852305e98ac43ca59f5bc","impliedFormat":1},{"version":"e6fa9ad47c5f71ff733744a029d1dc472c618de53804eae08ffc243b936f87ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"a6f137d651076822d4fe884287e68fd61785a0d3d1fdb250a5059b691fa897db","impliedFormat":1},{"version":"24826ed94a78d5c64bd857570fdbd96229ad41b5cb654c08d75a9845e3ab7dde","impliedFormat":1},{"version":"8b479a130ccb62e98f11f136d3ac80f2984fdc07616516d29881f3061f2dd472","impliedFormat":1},{"version":"928af3d90454bf656a52a48679f199f64c1435247d6189d1caf4c68f2eaf921f","affectsGlobalScope":true,"impliedFormat":1},{"version":"bceb58df66ab8fb00170df20cd813978c5ab84be1d285710c4eb005d8e9d8efb","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"4f9d8ca0c417b67b69eeb54c7ca1bedd7b56034bb9bfd27c5d4f3bc4692daca7","impliedFormat":1},{"version":"0cb167c371eaa8c869f8a7656a7296f2e4fae43b4d8b803a680236b24794e5f9","impliedFormat":1},{"version":"0a839dba0287cc0481ad4beedd48a1c64acf1e212ae865d1315f7007ca215161","impliedFormat":1},{"version":"38dc4655376cd1a4bd6bb3763d92949233e33d38d3dd3cbea7bbf218175a38ef","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"d61e0a64cd175208ac0b83670151a9a6b5916f0d1ffcdc5c29c90b1cebfc5045","affectsGlobalScope":true,"impliedFormat":1},{"version":"18fd40412d102c5564136f29735e5d1c3b455b8a37f920da79561f1fde068208","impliedFormat":1},{"version":"48a679952eefe4cb776d5a0e1ccba2d3eb53b57448bbb7abc1fcebcbd5440188","impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"2d14da6ecb49bf828d83948765ec2d3a579d476bbb9645e749610baa6ec880ca","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"5b7aa3c4c1a5d81b411e8cb302b45507fea9358d3569196b27eb1a27ae3a90ef","affectsGlobalScope":true,"impliedFormat":1},{"version":"5987a903da92c7462e0b35704ce7da94d7fdc4b89a984871c0e2b87a8aae9e69","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea08a0345023ade2b47fbff5a76d0d0ed8bff10bc9d22b83f40858a8e941501c","impliedFormat":1},{"version":"0aef708fb4c7a6b915e8305cbfac40cd207b032dbaabe9a01889a5fff3254681","impliedFormat":1},{"version":"ae062ce7d9510060c5d7e7952ae379224fb3f8f2dd74e88959878af2057c143b","impliedFormat":1},{"version":"ad9bdafb4e7abf14cc53ce7970486a84c87831e62891e5dfe798ddcd55e84701","affectsGlobalScope":true,"impliedFormat":1},{"version":"358765d5ea8afd285d4fd1532e78b88273f18cb3f87403a9b16fef61ac9fdcfe","impliedFormat":1},{"version":"71d3ae6a5e73ca4130762560425e00984ebaff64d5353a3333d1bb7eb86ef336","impliedFormat":1},{"version":"4371055bb001f40596e2e236b27583e13bf11e75d937962f8947d56519237fb8","impliedFormat":1},{"version":"89189df027e8910200a4b65af1e29a996225cf25975f5c438fbe9361c008fc6b","impliedFormat":1},{"version":"4555baaea5dfc93e0c0ba3fc326b0ba3ad50bb2ab887fa2dff49c7da7bd3bcaa","impliedFormat":1},{"version":"751764bb94219b4ce8f5475dc35d3de2e432fea01a0c9610cd7f69ad05e398c6","impliedFormat":1},{"version":"2e23be37a190953f60cdc4a62f89e5dfe4d6c64f38c71564bc0fb63c7810c9a1","impliedFormat":1}],"root":[62,[161,165]],"options":{"allowUnreachableCode":false,"allowUnusedLabels":false,"composite":true,"declaration":true,"declarationMap":true,"esModuleInterop":true,"exactOptionalPropertyTypes":true,"module":199,"noFallthroughCasesInSwitch":true,"noImplicitOverride":true,"noImplicitReturns":true,"noPropertyAccessFromIndexSignature":true,"noUncheckedIndexedAccess":true,"noUnusedLocals":true,"noUnusedParameters":true,"outDir":"./","rootDir":"../src","skipLibCheck":true,"sourceMap":true,"strict":true,"target":10,"tsBuildInfoFile":"./.tsbuildinfo","useUnknownInCatchVariables":true,"verbatimModuleSyntax":true},"referencedMap":[[168,1],[166,2],[276,3],[277,4],[278,2],[221,5],[222,5],[223,6],[174,7],[224,8],[225,9],[226,10],[169,2],[172,11],[170,2],[171,2],[227,12],[228,13],[229,14],[230,15],[231,16],[232,17],[233,17],[234,18],[235,19],[236,20],[237,21],[175,2],[173,2],[238,22],[239,23],[240,24],[274,25],[241,26],[242,2],[243,27],[244,28],[245,29],[246,30],[247,31],[248,32],[249,33],[250,34],[251,35],[252,35],[253,36],[254,2],[255,37],[256,38],[258,39],[257,40],[259,41],[260,42],[261,43],[262,44],[263,45],[264,46],[265,47],[266,48],[267,49],[268,50],[269,51],[270,52],[271,53],[176,2],[177,2],[178,2],[217,54],[218,2],[219,2],[220,41],[272,55],[273,56],[279,57],[275,58],[167,2],[179,2],[60,2],[61,2],[12,2],[11,2],[2,2],[13,2],[14,2],[15,2],[16,2],[17,2],[18,2],[19,2],[20,2],[3,2],[21,2],[22,2],[4,2],[23,2],[27,2],[24,2],[25,2],[26,2],[28,2],[29,2],[30,2],[5,2],[31,2],[32,2],[33,2],[34,2],[6,2],[38,2],[35,2],[36,2],[37,2],[39,2],[7,2],[40,2],[45,2],[46,2],[41,2],[42,2],[43,2],[44,2],[8,2],[50,2],[47,2],[48,2],[49,2],[51,2],[9,2],[52,2],[53,2],[54,2],[56,2],[55,2],[57,2],[58,2],[10,2],[59,2],[1,2],[195,59],[205,60],[194,59],[215,61],[186,62],[185,63],[214,64],[208,65],[213,66],[188,67],[202,68],[187,69],[211,70],[183,71],[182,64],[212,72],[184,73],[189,74],[190,2],[193,74],[180,2],[216,75],[206,76],[197,77],[198,78],[200,79],[196,80],[199,81],[209,64],[191,82],[192,83],[201,84],[181,85],[204,76],[203,74],[207,2],[210,86],[158,87],[152,88],[156,89],[153,89],[149,88],[157,90],[154,91],[155,89],[150,92],[151,93],[145,94],[86,95],[88,96],[144,2],[87,97],[148,98],[147,99],[146,100],[79,2],[89,95],[90,2],[81,101],[85,102],[80,2],[82,103],[83,104],[84,2],[91,105],[92,105],[93,105],[94,105],[95,105],[96,105],[97,105],[98,105],[99,105],[100,105],[101,105],[102,105],[103,105],[104,105],[106,105],[105,105],[107,105],[108,105],[109,105],[110,105],[111,105],[143,106],[112,105],[113,105],[114,105],[115,105],[116,105],[117,105],[118,105],[119,105],[120,105],[121,105],[122,105],[123,105],[124,105],[126,105],[125,105],[127,105],[128,105],[129,105],[130,105],[131,105],[132,105],[133,105],[134,105],[135,105],[136,105],[137,105],[138,105],[139,105],[142,105],[140,105],[141,105],[159,107],[69,108],[70,2],[71,108],[65,109],[78,110],[76,111],[74,112],[77,113],[73,113],[72,114],[75,2],[160,115],[64,2],[66,114],[63,2],[67,2],[68,2],[62,2],[163,116],[165,117],[164,118],[162,119],[161,120]],"latestChangedDtsFile":"./index.d.ts","version":"5.9.3"}
package/dist/args.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Render captured step arguments the way a developer would have written them.
3
+ *
4
+ * `StepRecord.args` is `unknown[]` — whatever the page object was called with,
5
+ * already redacted. `args.join(', ')` typechecks and looks fine in a unit test
6
+ * full of strings, then prints `[object Object]` against the real suite, where
7
+ * the interesting calls take objects: `expectCardData({ name: '…' })`.
8
+ *
9
+ * JSON.stringify is the other tempting shortcut and it is worse in a subtler
10
+ * way: it quotes keys, so `{"name":"Fitzgerald BJJ"}` shows a reader two
11
+ * quoted strings and no signal about which one is the domain value they should
12
+ * be looking for.
13
+ */
14
+ export declare function formatArgs(args: readonly unknown[]): string;
15
+ //# sourceMappingURL=args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAgCH,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,MAAM,CAE3D"}
package/dist/args.js ADDED
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Render captured step arguments the way a developer would have written them.
3
+ *
4
+ * `StepRecord.args` is `unknown[]` — whatever the page object was called with,
5
+ * already redacted. `args.join(', ')` typechecks and looks fine in a unit test
6
+ * full of strings, then prints `[object Object]` against the real suite, where
7
+ * the interesting calls take objects: `expectCardData({ name: '…' })`.
8
+ *
9
+ * JSON.stringify is the other tempting shortcut and it is worse in a subtler
10
+ * way: it quotes keys, so `{"name":"Fitzgerald BJJ"}` shows a reader two
11
+ * quoted strings and no signal about which one is the domain value they should
12
+ * be looking for.
13
+ */
14
+ const MAX_STRING = 60;
15
+ function formatValue(value, depth) {
16
+ if (typeof value === 'string') {
17
+ const clipped = value.length > MAX_STRING ? `${value.slice(0, MAX_STRING - 1)}…` : value;
18
+ return `'${clipped}'`;
19
+ }
20
+ if (value === null)
21
+ return 'null';
22
+ if (value === undefined)
23
+ return 'undefined';
24
+ if (typeof value === 'number' || typeof value === 'boolean')
25
+ return String(value);
26
+ // Depth-limited: a page object handed a Playwright locator or a whole DTO
27
+ // would otherwise print a wall of nesting nobody reads.
28
+ if (depth >= 2)
29
+ return Array.isArray(value) ? '[…]' : '{…}';
30
+ if (Array.isArray(value)) {
31
+ if (value.length === 0)
32
+ return '[]';
33
+ return `[${value.map(v => formatValue(v, depth + 1)).join(', ')}]`;
34
+ }
35
+ if (typeof value === 'object') {
36
+ const entries = Object.entries(value);
37
+ if (entries.length === 0)
38
+ return '{}';
39
+ const inner = entries.map(([k, v]) => `${k}: ${formatValue(v, depth + 1)}`).join(', ');
40
+ return `{ ${inner} }`;
41
+ }
42
+ return String(value);
43
+ }
44
+ export function formatArgs(args) {
45
+ return args.map(arg => formatValue(arg, 0)).join(', ');
46
+ }
47
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,UAAU,GAAG,EAAE,CAAC;AAEtB,SAAS,WAAW,CAAC,KAAc,EAAE,KAAa;IAChD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;QACzF,OAAO,IAAI,OAAO,GAAG,CAAC;IACxB,CAAC;IACD,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IAClC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,WAAW,CAAC;IAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IAElF,0EAA0E;IAC1E,wDAAwD;IACxD,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;IAE5D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACpC,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IACrE,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACtC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,WAAW,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvF,OAAO,KAAK,KAAK,IAAI,CAAC;IACxB,CAAC;IAED,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAwB;IACjD,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzD,CAAC"}
package/dist/html.d.ts ADDED
@@ -0,0 +1,27 @@
1
+ /**
2
+ * HTML report — a single self-contained file.
3
+ *
4
+ * Deliberately NOT a replacement for the Playwright HTML report. That one
5
+ * already shows traces, screenshots and stacks, and does it better. This one
6
+ * answers the question Playwright's cannot: *why* did these fail, and is it
7
+ * one cause or twelve? So each card leads with intent and classification, and
8
+ * the stack is the last thing on the page.
9
+ *
10
+ * Self-contained is a hard constraint, not a preference. The file is consumed
11
+ * as a CI artifact — downloaded, unzipped, opened from file://, often on a
12
+ * laptop with no network. A single CDN <script> makes it a blank page, and it
13
+ * would be a blank page for the person debugging a failed release.
14
+ */
15
+ import type { ReportInput } from './markdown.js';
16
+ /**
17
+ * Escape for HTML TEXT and double-quoted attributes.
18
+ *
19
+ * Every string on this page originates outside it: test titles, error
20
+ * messages, ARIA snapshots scraped from the app under test. A title
21
+ * containing `<img>` must render as text — not because a test author is an
22
+ * attacker, but because the page silently breaking is indistinguishable from
23
+ * the tool being wrong.
24
+ */
25
+ export declare function escapeHtml(value: string): string;
26
+ export declare function renderHtml(input: ReportInput): string;
27
+ //# sourceMappingURL=html.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../src/html.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,eAAe,CAAC;AAE/D;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOhD;AA2MD,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAyCrD"}
package/dist/html.js ADDED
@@ -0,0 +1,256 @@
1
+ /**
2
+ * HTML report — a single self-contained file.
3
+ *
4
+ * Deliberately NOT a replacement for the Playwright HTML report. That one
5
+ * already shows traces, screenshots and stacks, and does it better. This one
6
+ * answers the question Playwright's cannot: *why* did these fail, and is it
7
+ * one cause or twelve? So each card leads with intent and classification, and
8
+ * the stack is the last thing on the page.
9
+ *
10
+ * Self-contained is a hard constraint, not a preference. The file is consumed
11
+ * as a CI artifact — downloaded, unzipped, opened from file://, often on a
12
+ * laptop with no network. A single CDN <script> makes it a blank page, and it
13
+ * would be a blank page for the person debugging a failed release.
14
+ */
15
+ import { formatArgs } from './args.js';
16
+ import { formatDuration } from './merge.js';
17
+ /**
18
+ * Escape for HTML TEXT and double-quoted attributes.
19
+ *
20
+ * Every string on this page originates outside it: test titles, error
21
+ * messages, ARIA snapshots scraped from the app under test. A title
22
+ * containing `<img>` must render as text — not because a test author is an
23
+ * attacker, but because the page silently breaking is indistinguishable from
24
+ * the tool being wrong.
25
+ */
26
+ export function escapeHtml(value) {
27
+ return value
28
+ .replace(/&/g, '&amp;')
29
+ .replace(/</g, '&lt;')
30
+ .replace(/>/g, '&gt;')
31
+ .replace(/"/g, '&quot;')
32
+ .replace(/'/g, '&#39;');
33
+ }
34
+ const STYLES = `
35
+ :root {
36
+ color-scheme: light dark;
37
+ --bg: #ffffff; --panel: #f6f7f9; --border: #d8dce2; --fg: #14181f;
38
+ --muted: #5b6472; --accent: #2563eb; --fail: #b42318; --warn: #b54708;
39
+ --pass: #067647; --code: #eef1f5;
40
+ }
41
+ @media (prefers-color-scheme: dark) {
42
+ :root {
43
+ --bg: #0d1117; --panel: #161b22; --border: #2b323c; --fg: #e6edf3;
44
+ --muted: #9198a1; --accent: #58a6ff; --fail: #ff7b72; --warn: #d29922;
45
+ --pass: #3fb950; --code: #1c2128;
46
+ }
47
+ }
48
+ * { box-sizing: border-box; }
49
+ body {
50
+ margin: 0; padding: 2rem 1.25rem; background: var(--bg); color: var(--fg);
51
+ font: 15px/1.55 ui-sans-serif, -apple-system, "Segoe UI", system-ui, sans-serif;
52
+ }
53
+ .wrap { max-width: 62rem; margin: 0 auto; }
54
+ h1 { font-size: 1.5rem; margin: 0 0 .25rem; }
55
+ h2 { font-size: 1.05rem; margin: 2.25rem 0 .75rem; }
56
+ .sub { color: var(--muted); font-size: .875rem; margin-bottom: 1.5rem; }
57
+ .totals { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 1rem; }
58
+ .pill {
59
+ border: 1px solid var(--border); border-radius: 999px; padding: .2rem .7rem;
60
+ font-size: .8rem; background: var(--panel);
61
+ }
62
+ .pill.fail { color: var(--fail); border-color: currentColor; }
63
+ .pill.pass { color: var(--pass); border-color: currentColor; }
64
+ .pill.warn { color: var(--warn); border-color: currentColor; }
65
+ .card {
66
+ border: 1px solid var(--border); border-radius: 8px; background: var(--panel);
67
+ margin-bottom: .75rem; overflow: hidden;
68
+ }
69
+ .card > summary {
70
+ cursor: pointer; padding: .75rem 1rem; list-style: none;
71
+ display: flex; gap: .6rem; align-items: baseline; flex-wrap: wrap;
72
+ }
73
+ .card > summary::-webkit-details-marker { display: none; }
74
+ .card > summary:hover { background: var(--code); }
75
+ .kind {
76
+ font-size: .72rem; text-transform: uppercase; letter-spacing: .04em;
77
+ color: var(--fail); font-weight: 600; white-space: nowrap;
78
+ }
79
+ .title { font-weight: 500; }
80
+ .where { color: var(--muted); font-size: .8rem; margin-left: auto; }
81
+ .body { padding: 0 1rem 1rem; }
82
+ .row { display: grid; grid-template-columns: 7.5rem 1fr; gap: .35rem .75rem; margin: .5rem 0; }
83
+ .label { color: var(--muted); font-size: .8rem; padding-top: .15rem; }
84
+ code, pre {
85
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
86
+ font-size: .82rem;
87
+ }
88
+ code { background: var(--code); padding: .1rem .35rem; border-radius: 4px; }
89
+ pre {
90
+ background: var(--code); padding: .7rem .85rem; border-radius: 6px;
91
+ overflow-x: auto; margin: 0; max-height: 22rem;
92
+ }
93
+ table { border-collapse: collapse; width: 100%; font-size: .85rem; }
94
+ th, td { text-align: left; padding: .45rem .6rem; border-bottom: 1px solid var(--border); }
95
+ th { color: var(--muted); font-weight: 500; font-size: .78rem; }
96
+ tbody tr:last-child td { border-bottom: none; }
97
+ .scroll { overflow-x: auto; border: 1px solid var(--border); border-radius: 8px; background: var(--panel); }
98
+ .empty { color: var(--muted); font-style: italic; }
99
+ .arrow { color: var(--accent); }
100
+ footer { color: var(--muted); font-size: .78rem; margin-top: 3rem; }
101
+ `;
102
+ function intentBlock(bundle) {
103
+ const step = bundle.intent.failingStep;
104
+ if (step === null)
105
+ return `<span class="empty">no instrumented step</span>`;
106
+ const call = `${step.pageObject}.${step.method}(${formatArgs(step.args)})`;
107
+ return `<code>${escapeHtml(call)}</code>`;
108
+ }
109
+ function candidatesBlock(bundle) {
110
+ const candidates = bundle.page.candidates;
111
+ if (candidates.length === 0)
112
+ return '';
113
+ // matchCount is -1 when nothing has resolved the candidate against a live
114
+ // page — the reporter has no browser, so it records "not checked" rather
115
+ // than asserting a uniqueness nobody measured. Rendering that sentinel as a
116
+ // number prints "-1 matches — ambiguous" next to the CORRECT candidate,
117
+ // telling the reader it is disqualified from healing when it is not.
118
+ const items = candidates
119
+ .slice(0, 5)
120
+ .map(c => {
121
+ const note = c.matchCount < 0
122
+ ? `unverified · distance ${c.semanticDistance.toFixed(2)}`
123
+ : c.matchCount === 1
124
+ ? `unique · distance ${c.semanticDistance.toFixed(2)}`
125
+ : `${c.matchCount} matches — ambiguous`;
126
+ return `<div><code>${escapeHtml(c.expression)}</code> <span class="where">${escapeHtml(note)}</span></div>`;
127
+ })
128
+ .join('');
129
+ return `<div class="row"><span class="label">candidates</span><div>${items}</div></div>
130
+ <div class="row"><span class="label"></span><div class="sub">Ranked by name distance. &ldquo;unverified&rdquo; means no browser
131
+ has resolved it yet &mdash; <code>aplaytest heal</code> checks uniqueness against the live page before proposing.</div></div>`;
132
+ }
133
+ function failureCard(bundle) {
134
+ const file = bundle.test.file.split('/').pop() ?? bundle.test.file;
135
+ const consoleErrors = bundle.console.errors.slice(0, 5);
136
+ const failedRequests = bundle.network.failed.slice(0, 5);
137
+ const parts = [];
138
+ parts.push(`<div class="row"><span class="label">intent</span><div>${intentBlock(bundle)}</div></div>`);
139
+ if (bundle.intent.selector !== null) {
140
+ parts.push(`<div class="row"><span class="label">selector</span><div><code>${escapeHtml(bundle.intent.selector)}</code></div></div>`);
141
+ }
142
+ parts.push(candidatesBlock(bundle));
143
+ parts.push(`<div class="row"><span class="label">page</span><div><code>${escapeHtml(bundle.page.url)}</code></div></div>`);
144
+ if (consoleErrors.length > 0) {
145
+ parts.push(`<div class="row"><span class="label">console</span><pre>${escapeHtml(consoleErrors.join('\n'))}</pre></div>`);
146
+ }
147
+ if (failedRequests.length > 0) {
148
+ const text = failedRequests
149
+ .map(r => `${r.status ?? 'ERR'} ${r.method} ${r.url}`)
150
+ .join('\n');
151
+ parts.push(`<div class="row"><span class="label">network</span><pre>${escapeHtml(text)}</pre></div>`);
152
+ }
153
+ // Last, and only here: the raw message. It is the thing everyone already
154
+ // has, so it does not get to be the headline.
155
+ parts.push(`<div class="row"><span class="label">message</span><pre>${escapeHtml(bundle.failure.message)}</pre></div>`);
156
+ return `<details class="card">
157
+ <summary>
158
+ <span class="kind">${escapeHtml(bundle.failure.kind.replace(/_/g, ' '))}</span>
159
+ <span class="title">${escapeHtml(bundle.test.title)}</span>
160
+ <span class="where">${escapeHtml(file)}:${bundle.test.line} · ${escapeHtml(bundle.test.project)}</span>
161
+ </summary>
162
+ <div class="body">${parts.join('')}</div>
163
+ </details>`;
164
+ }
165
+ function flakyTable(flaky) {
166
+ if (flaky.length === 0)
167
+ return '';
168
+ const rows = flaky
169
+ .map(f => `<tr>
170
+ <td>${escapeHtml(f.title)}</td>
171
+ <td>${escapeHtml(f.project)}</td>
172
+ <td>${f.score.toFixed(2)}</td>
173
+ <td>${escapeHtml(f.class)}</td>
174
+ <td>${escapeHtml(f.prescription)}</td>
175
+ </tr>`)
176
+ .join('');
177
+ return `<h2>Flaky</h2>
178
+ <div class="scroll"><table>
179
+ <thead><tr><th>test</th><th>project</th><th>score</th><th>cause</th><th>prescription</th></tr></thead>
180
+ <tbody>${rows}</tbody>
181
+ </table></div>`;
182
+ }
183
+ function healTable(input) {
184
+ const heals = (input.heals ?? []).filter(h => h.validated);
185
+ if (heals.length === 0)
186
+ return '';
187
+ const rows = heals
188
+ .map(h => `<tr>
189
+ <td>${escapeHtml(h.title)}</td>
190
+ <td><code>${escapeHtml(h.from)}</code> <span class="arrow">&rarr;</span> <code>${escapeHtml(h.to)}</code></td>
191
+ <td>${(h.confidence * 100).toFixed(0)}%</td>
192
+ </tr>`)
193
+ .join('');
194
+ return `<h2>Suggested selector repairs</h2>
195
+ <div class="scroll"><table>
196
+ <thead><tr><th>test</th><th>change</th><th>confidence</th></tr></thead>
197
+ <tbody>${rows}</tbody>
198
+ </table></div>
199
+ <p class="sub">Each was verified by re-running the test with the patch applied, and every
200
+ proposal is recorded in the heal ledger. Review before applying &mdash; a passing test with the
201
+ wrong selector is worse than a failing one.</p>`;
202
+ }
203
+ function totalsBar(run) {
204
+ const pills = [];
205
+ if (run.totals.failed > 0)
206
+ pills.push(`<span class="pill fail">${run.totals.failed} failed</span>`);
207
+ pills.push(`<span class="pill pass">${run.totals.passed} passed</span>`);
208
+ if (run.totals.flaky > 0)
209
+ pills.push(`<span class="pill warn">${run.totals.flaky} flaky</span>`);
210
+ if (run.totals.skipped > 0)
211
+ pills.push(`<span class="pill">${run.totals.skipped} skipped</span>`);
212
+ pills.push(`<span class="pill">${formatDuration(run.totals.durationMs)}</span>`);
213
+ if (run.shardsMerged > 1)
214
+ pills.push(`<span class="pill">${run.shardsMerged} shards</span>`);
215
+ return `<div class="totals">${pills.join('')}</div>`;
216
+ }
217
+ export function renderHtml(input) {
218
+ const { run } = input;
219
+ const meta = [
220
+ `run ${escapeHtml(run.runId)}`,
221
+ run.branch === null ? null : escapeHtml(run.branch),
222
+ run.commit === null ? null : escapeHtml(run.commit.slice(0, 7)),
223
+ escapeHtml(run.startedAt),
224
+ ]
225
+ .filter((p) => p !== null)
226
+ .join(' · ');
227
+ const failures = input.failures.length === 0
228
+ ? '<p class="empty">No failures captured.</p>'
229
+ : input.failures.map(failureCard).join('\n');
230
+ return `<!doctype html>
231
+ <html lang="en">
232
+ <head>
233
+ <meta charset="utf-8">
234
+ <meta name="viewport" content="width=device-width, initial-scale=1">
235
+ <title>aplaytest report — ${escapeHtml(run.runId)}</title>
236
+ <style>${STYLES}</style>
237
+ </head>
238
+ <body>
239
+ <div class="wrap">
240
+ <h1>Test run</h1>
241
+ <div class="sub">${meta}</div>
242
+ ${totalsBar(run)}
243
+ <h2>Failures</h2>
244
+ ${failures}
245
+ ${flakyTable(input.flaky ?? [])}
246
+ ${healTable(input)}
247
+ <footer>
248
+ Generated by atest. Every number on this page is measured from recorded attempts &mdash;
249
+ no model was consulted to produce it.
250
+ </footer>
251
+ </div>
252
+ </body>
253
+ </html>
254
+ `;
255
+ }
256
+ //# sourceMappingURL=html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../src/html.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @aplaytest/report — shard merge, PR comment, and the self-contained HTML report.
3
+ *
4
+ * Wholly deterministic, like @aplaytest/flaky: this package renders what was
5
+ * measured and never asks a model to phrase it. The report is what people read
6
+ * when a release is broken at 2am, and it has to be identical every time it is
7
+ * generated from the same inputs.
8
+ */
9
+ export { mergeRuns, formatDuration } from './merge.js';
10
+ export type { MergedRun } from './merge.js';
11
+ export { renderMarkdown, fence, cell, MAX_COMMENT_CHARS, COMMENT_MARKER } from './markdown.js';
12
+ export type { ReportInput, FlakySummary, HealSummary } from './markdown.js';
13
+ export { renderHtml, escapeHtml } from './html.js';
14
+ export { formatArgs } from './args.js';
15
+ export { loadRuns, loadEvidence, orderFailures } from './load.js';
16
+ export type { LoadResult } from './load.js';
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACvD,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/F,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5E,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAClE,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @aplaytest/report — shard merge, PR comment, and the self-contained HTML report.
3
+ *
4
+ * Wholly deterministic, like @aplaytest/flaky: this package renders what was
5
+ * measured and never asks a model to phrase it. The report is what people read
6
+ * when a release is broken at 2am, and it has to be identical every time it is
7
+ * generated from the same inputs.
8
+ */
9
+ export { mergeRuns, formatDuration } from './merge.js';
10
+ export { renderMarkdown, fence, cell, MAX_COMMENT_CHARS, COMMENT_MARKER } from './markdown.js';
11
+ export { renderHtml, escapeHtml } from './html.js';
12
+ export { formatArgs } from './args.js';
13
+ export { loadRuns, loadEvidence, orderFailures } from './load.js';
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGvD,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/F,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC"}
package/dist/load.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Read run records and evidence bundles off disk.
3
+ *
4
+ * Everything here degrades rather than throws. Report generation runs at the
5
+ * end of a CI job that has often already failed, frequently over artifacts
6
+ * downloaded from four shards where one upload was cancelled. Refusing to
7
+ * produce a report because one file is corrupt would withhold the other three
8
+ * shards' worth of information at exactly the moment it is wanted.
9
+ */
10
+ import type { EvidenceBundle, RunRecord } from '@aplaytest/core';
11
+ export interface LoadResult<T> {
12
+ readonly items: readonly T[];
13
+ /** Files that could not be used, with the reason — surfaced, never silent. */
14
+ readonly skipped: readonly {
15
+ readonly file: string;
16
+ readonly reason: string;
17
+ }[];
18
+ }
19
+ export declare function loadRuns(dir: string): Promise<LoadResult<RunRecord>>;
20
+ /** Evidence is stored one directory per run, so this recurses one level. */
21
+ export declare function loadEvidence(dir: string): Promise<LoadResult<EvidenceBundle>>;
22
+ export declare function orderFailures(bundles: readonly EvidenceBundle[]): EvidenceBundle[];
23
+ //# sourceMappingURL=load.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../src/load.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjE,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;IAC7B,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACjF;AAsDD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAEpE;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAE7E;AAwBD,wBAAgB,aAAa,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,GAAG,cAAc,EAAE,CASlF"}
package/dist/load.js ADDED
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Read run records and evidence bundles off disk.
3
+ *
4
+ * Everything here degrades rather than throws. Report generation runs at the
5
+ * end of a CI job that has often already failed, frequently over artifacts
6
+ * downloaded from four shards where one upload was cancelled. Refusing to
7
+ * produce a report because one file is corrupt would withhold the other three
8
+ * shards' worth of information at exactly the moment it is wanted.
9
+ */
10
+ import { readFile, readdir } from 'node:fs/promises';
11
+ import { join } from 'node:path';
12
+ async function readJsonDir(dir, validate, recurse) {
13
+ const items = [];
14
+ const skipped = [];
15
+ const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
16
+ for (const entry of entries) {
17
+ const path = join(dir, entry.name);
18
+ if (entry.isDirectory()) {
19
+ if (!recurse)
20
+ continue;
21
+ const nested = await readJsonDir(path, validate, false);
22
+ items.push(...nested.items);
23
+ skipped.push(...nested.skipped);
24
+ continue;
25
+ }
26
+ if (!entry.name.endsWith('.json'))
27
+ continue;
28
+ try {
29
+ const parsed = JSON.parse(await readFile(path, 'utf8'));
30
+ if (validate(parsed))
31
+ items.push(parsed);
32
+ else
33
+ skipped.push({ file: entry.name, reason: 'not the expected shape' });
34
+ }
35
+ catch (error) {
36
+ skipped.push({ file: entry.name, reason: error instanceof Error ? error.message : 'unreadable' });
37
+ }
38
+ }
39
+ return { items, skipped };
40
+ }
41
+ function isRunRecord(value) {
42
+ if (typeof value !== 'object' || value === null)
43
+ return false;
44
+ const record = value;
45
+ return typeof record['runId'] === 'string' && Array.isArray(record['attempts']);
46
+ }
47
+ function isEvidenceBundle(value) {
48
+ if (typeof value !== 'object' || value === null)
49
+ return false;
50
+ const record = value;
51
+ return (typeof record['id'] === 'string' &&
52
+ typeof record['failure'] === 'object' &&
53
+ record['failure'] !== null &&
54
+ typeof record['test'] === 'object' &&
55
+ record['test'] !== null);
56
+ }
57
+ export function loadRuns(dir) {
58
+ return readJsonDir(dir, isRunRecord, false);
59
+ }
60
+ /** Evidence is stored one directory per run, so this recurses one level. */
61
+ export function loadEvidence(dir) {
62
+ return readJsonDir(dir, isEvidenceBundle, true);
63
+ }
64
+ /**
65
+ * Order failures so the most informative card is first.
66
+ *
67
+ * Kind ordering is a judgement, not a preference: an app error or a contract
68
+ * violation is a real defect and should be read before a locator miss, which
69
+ * is frequently a consequence of it. Sorting by test name instead puts an
70
+ * alphabetically lucky symptom above its own cause.
71
+ */
72
+ const KIND_PRIORITY = [
73
+ 'app_error',
74
+ 'schema_violation',
75
+ 'http_status',
76
+ 'network_error',
77
+ 'navigation_failure',
78
+ 'assertion_value',
79
+ 'locator_not_found',
80
+ 'locator_ambiguous',
81
+ 'assertion_visibility',
82
+ 'timeout',
83
+ 'infra',
84
+ ];
85
+ export function orderFailures(bundles) {
86
+ return [...bundles].sort((a, b) => {
87
+ const rankA = KIND_PRIORITY.indexOf(a.failure.kind);
88
+ const rankB = KIND_PRIORITY.indexOf(b.failure.kind);
89
+ const normA = rankA === -1 ? KIND_PRIORITY.length : rankA;
90
+ const normB = rankB === -1 ? KIND_PRIORITY.length : rankB;
91
+ if (normA !== normB)
92
+ return normA - normB;
93
+ return a.test.title.localeCompare(b.test.title);
94
+ });
95
+ }
96
+ //# sourceMappingURL=load.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.js","sourceRoot":"","sources":["../src/load.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Markdown renderer — the PR comment.
3
+ *
4
+ * This is the surface most people will ever see of atest, so it is held to a
5
+ * stricter rule than the HTML report: SAY LESS. A comment nobody reads is
6
+ * worse than no comment, and a comment that reprints the Playwright output
7
+ * they already have is exactly that.
8
+ *
9
+ * Three bounds, all of them defensive:
10
+ * · GitHub hard-truncates a comment at 65536 characters. Truncation mid-
11
+ * table produces a broken render, so we cut at a section boundary and say
12
+ * what was cut.
13
+ * · Failure text is untrusted. An error message containing ``` would escape
14
+ * a fenced block and let the remainder of the message render as markup.
15
+ * · Nothing here calls a model. The comment must post during a provider
16
+ * outage.
17
+ */
18
+ import type { EvidenceBundle } from '@aplaytest/core';
19
+ import { type MergedRun } from './merge.js';
20
+ /** GitHub's limit is 65536; leave room for the surrounding template. */
21
+ export declare const MAX_COMMENT_CHARS = 60000;
22
+ /** Marker so CI can update its previous comment instead of posting a new one. */
23
+ export declare const COMMENT_MARKER = "<!-- atest-report -->";
24
+ export interface FlakySummary {
25
+ readonly title: string;
26
+ readonly project: string;
27
+ readonly score: number;
28
+ readonly class: string;
29
+ readonly prescription: string;
30
+ }
31
+ export interface HealSummary {
32
+ readonly title: string;
33
+ readonly file: string;
34
+ readonly from: string;
35
+ readonly to: string;
36
+ readonly confidence: number;
37
+ readonly validated: boolean;
38
+ }
39
+ export interface ReportInput {
40
+ readonly run: MergedRun;
41
+ readonly failures: readonly EvidenceBundle[];
42
+ readonly flaky?: readonly FlakySummary[] | undefined;
43
+ readonly heals?: readonly HealSummary[] | undefined;
44
+ readonly reportUrl?: string | undefined;
45
+ }
46
+ /**
47
+ * Wrap untrusted text in a fence long enough to contain it.
48
+ *
49
+ * An error message that itself contains ``` — a spec asserting on markdown, a
50
+ * snapshot of a code block — would otherwise close the fence early and let the
51
+ * rest of the message render as markup.
52
+ */
53
+ export declare function fence(content: string, lang?: string): string;
54
+ /** Escape the characters that would break out of a markdown TABLE CELL. */
55
+ export declare function cell(text: string): string;
56
+ export declare function renderMarkdown(input: ReportInput): string;
57
+ //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGtD,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5D,wEAAwE;AACxE,eAAO,MAAM,iBAAiB,QAAS,CAAC;AAExC,iFAAiF;AACjF,eAAO,MAAM,cAAc,0BAA0B,CAAC;AAEtD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;IAC7C,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,CAAC;IACrD,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,WAAW,EAAE,GAAG,SAAS,CAAC;IACpD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AAED;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,SAAK,GAAG,MAAM,CAIxD;AAED,2EAA2E;AAC3E,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzC;AAqID,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAsDzD"}
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Markdown renderer — the PR comment.
3
+ *
4
+ * This is the surface most people will ever see of atest, so it is held to a
5
+ * stricter rule than the HTML report: SAY LESS. A comment nobody reads is
6
+ * worse than no comment, and a comment that reprints the Playwright output
7
+ * they already have is exactly that.
8
+ *
9
+ * Three bounds, all of them defensive:
10
+ * · GitHub hard-truncates a comment at 65536 characters. Truncation mid-
11
+ * table produces a broken render, so we cut at a section boundary and say
12
+ * what was cut.
13
+ * · Failure text is untrusted. An error message containing ``` would escape
14
+ * a fenced block and let the remainder of the message render as markup.
15
+ * · Nothing here calls a model. The comment must post during a provider
16
+ * outage.
17
+ */
18
+ import { formatArgs } from './args.js';
19
+ import { formatDuration } from './merge.js';
20
+ /** GitHub's limit is 65536; leave room for the surrounding template. */
21
+ export const MAX_COMMENT_CHARS = 60_000;
22
+ /** Marker so CI can update its previous comment instead of posting a new one. */
23
+ export const COMMENT_MARKER = '<!-- atest-report -->';
24
+ /**
25
+ * Wrap untrusted text in a fence long enough to contain it.
26
+ *
27
+ * An error message that itself contains ``` — a spec asserting on markdown, a
28
+ * snapshot of a code block — would otherwise close the fence early and let the
29
+ * rest of the message render as markup.
30
+ */
31
+ export function fence(content, lang = '') {
32
+ const longest = [...content.matchAll(/`+/g)].reduce((max, m) => Math.max(max, m[0].length), 0);
33
+ const ticks = '`'.repeat(Math.max(3, longest + 1));
34
+ return `${ticks}${lang}\n${content}\n${ticks}`;
35
+ }
36
+ /** Escape the characters that would break out of a markdown TABLE CELL. */
37
+ export function cell(text) {
38
+ return text.replace(/\|/g, '\\|').replace(/\r?\n/g, ' ').trim();
39
+ }
40
+ function truncate(text, max) {
41
+ return text.length <= max ? text : `${text.slice(0, max - 1)}…`;
42
+ }
43
+ function verdictLine(run) {
44
+ const { totals } = run;
45
+ if (totals.failed > 0) {
46
+ return `**${totals.failed} failed**, ${totals.passed} passed`;
47
+ }
48
+ if (totals.flaky > 0) {
49
+ return `**All green** — ${totals.flaky} passed on retry`;
50
+ }
51
+ return `**All ${totals.passed} passed**`;
52
+ }
53
+ function intentOf(bundle) {
54
+ const step = bundle.intent.failingStep;
55
+ if (step !== null) {
56
+ return `${step.pageObject}.${step.method}(${truncate(formatArgs(step.args), 60)})`;
57
+ }
58
+ // No bound page object — a raw locator in the spec. Falling back to the test
59
+ // title prints it twice in adjacent columns, which reads as a rendering bug
60
+ // and wastes the one column that was meant to add information.
61
+ if (bundle.intent.selector !== null)
62
+ return truncate(bundle.intent.selector, 60);
63
+ return '—';
64
+ }
65
+ /**
66
+ * Render failures, grouped by kind, within a character budget.
67
+ *
68
+ * The budget is enforced GROUP BY GROUP rather than by dropping the section.
69
+ * Dropping it whole is what the obvious implementation does, and on a run with
70
+ * four thousand failures it produced a 153-character comment reading
71
+ * "1 section(s) omitted" — the single most important section discarded
72
+ * precisely when there was most to say. Partial beats absent: the largest
73
+ * groups are also the likeliest to share one cause, so the ones that fit are
74
+ * the ones worth having.
75
+ */
76
+ function failuresSection(failures, budget) {
77
+ if (failures.length === 0)
78
+ return [];
79
+ // Grouping by kind is the whole point: ten failures sharing one kind are
80
+ // usually one cause, and a flat list hides that.
81
+ const byKind = new Map();
82
+ for (const bundle of failures) {
83
+ const kind = bundle.failure.kind;
84
+ byKind.set(kind, [...(byKind.get(kind) ?? []), bundle]);
85
+ }
86
+ const header = ['### Failures', ''];
87
+ const lines = [...header];
88
+ let used = header.join('\n').length;
89
+ const ordered = [...byKind.entries()].sort((a, b) => b[1].length - a[1].length);
90
+ let shownGroups = 0;
91
+ let shownFailures = 0;
92
+ for (const [kind, bundles] of ordered) {
93
+ const group = [`**${kind.replace(/_/g, ' ')}** · ${bundles.length}`, '', '| test | intent | where |', '| --- | --- | --- |'];
94
+ for (const bundle of bundles.slice(0, 10)) {
95
+ const where = `${bundle.test.file.split('/').pop() ?? ''}:${bundle.test.line}`;
96
+ group.push(`| ${cell(truncate(bundle.test.title, 70))} | \`${cell(intentOf(bundle))}\` | ${cell(where)} |`);
97
+ }
98
+ if (bundles.length > 10)
99
+ group.push(`| _+${bundles.length - 10} more_ | | |`);
100
+ group.push('');
101
+ const size = group.join('\n').length + 1;
102
+ // Reserve room for the "not shown" footer so it can always be appended.
103
+ if (used + size > budget - 120)
104
+ break;
105
+ lines.push(...group);
106
+ used += size;
107
+ shownGroups += 1;
108
+ shownFailures += bundles.length;
109
+ }
110
+ const hiddenGroups = ordered.length - shownGroups;
111
+ if (hiddenGroups > 0) {
112
+ const hiddenFailures = failures.length - shownFailures;
113
+ lines.push(`_${hiddenFailures} further failure(s) across ${hiddenGroups} more kind(s) not shown — see the full report._`, '');
114
+ }
115
+ return lines;
116
+ }
117
+ function healsSection(heals) {
118
+ if (heals.length === 0)
119
+ return [];
120
+ // Unvalidated proposals are deliberately not shown. A suggestion that has
121
+ // not been re-run against the app is a guess, and a guess in a PR comment
122
+ // gets applied by someone who trusts the tool.
123
+ const validated = heals.filter(h => h.validated);
124
+ if (validated.length === 0)
125
+ return [];
126
+ const lines = ['### Suggested selector repairs', ''];
127
+ lines.push('| test | change | confidence |');
128
+ lines.push('| --- | --- | --- |');
129
+ for (const heal of validated.slice(0, 10)) {
130
+ lines.push(`| ${cell(truncate(heal.title, 60))} | \`${cell(heal.from)}\` → \`${cell(heal.to)}\` | ${(heal.confidence * 100).toFixed(0)}% |`);
131
+ }
132
+ lines.push('');
133
+ lines.push('_Each was verified by re-running the test with the patch applied. Review before applying — a passing test with the wrong selector is worse than a failing one._');
134
+ lines.push('');
135
+ return lines;
136
+ }
137
+ function flakySection(flaky) {
138
+ if (flaky.length === 0)
139
+ return [];
140
+ const lines = ['### Flaky', ''];
141
+ lines.push('| test | score | cause | do |');
142
+ lines.push('| --- | --- | --- | --- |');
143
+ for (const entry of flaky.slice(0, 10)) {
144
+ lines.push(`| ${cell(truncate(entry.title, 60))} | ${entry.score.toFixed(2)} | ${cell(entry.class)} | ${cell(entry.prescription)} |`);
145
+ }
146
+ if (flaky.length > 10)
147
+ lines.push(`| _+${flaky.length - 10} more_ | | | |`);
148
+ lines.push('');
149
+ return lines;
150
+ }
151
+ export function renderMarkdown(input) {
152
+ const { run } = input;
153
+ const head = [
154
+ COMMENT_MARKER,
155
+ `## ${verdictLine(run)}`,
156
+ '',
157
+ [
158
+ `${run.totals.tests} tests`,
159
+ `${formatDuration(run.totals.durationMs)}`,
160
+ run.shardsMerged > 1 ? `${run.shardsMerged} shards` : null,
161
+ run.totals.flaky > 0 ? `${run.totals.flaky} flaky` : null,
162
+ run.totals.skipped > 0 ? `${run.totals.skipped} skipped` : null,
163
+ ]
164
+ .filter((p) => p !== null)
165
+ .join(' · '),
166
+ '',
167
+ ];
168
+ const foot = [];
169
+ if (input.reportUrl !== undefined)
170
+ foot.push(`[Full report](${input.reportUrl})`);
171
+ foot.push(`<sub>atest · run \`${run.runId}\`${run.commit === null ? '' : ` · ${run.commit.slice(0, 7)}`}</sub>`);
172
+ let out = head.join('\n');
173
+ const tail = `\n${foot.join('\n')}\n`;
174
+ // Failures get the bulk of the budget and truncate internally; the two
175
+ // advisory sections take what is left. Ordered by what a reviewer acts on
176
+ // first — failures block the merge, flake is a background concern, heals
177
+ // are optional suggestions.
178
+ const available = MAX_COMMENT_CHARS - out.length - tail.length;
179
+ const sections = [
180
+ failuresSection(input.failures, Math.floor(available * 0.75)),
181
+ input.flaky === undefined ? [] : flakySection(input.flaky),
182
+ input.heals === undefined ? [] : healsSection(input.heals),
183
+ ];
184
+ let dropped = 0;
185
+ for (const section of sections) {
186
+ if (section.length === 0)
187
+ continue;
188
+ const text = `${section.join('\n')}\n`;
189
+ // Section boundaries only: cutting mid-table renders as broken markup.
190
+ if (out.length + text.length + tail.length > MAX_COMMENT_CHARS) {
191
+ dropped += 1;
192
+ continue;
193
+ }
194
+ out += text;
195
+ }
196
+ if (dropped > 0) {
197
+ out += `\n_${dropped} advisory section(s) omitted — comment size limit. See the full report._\n`;
198
+ }
199
+ return out + tail;
200
+ }
201
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Merge sharded run records into one view.
3
+ *
4
+ * CI writes one record per shard, all carrying the same run id — that is why
5
+ * the reporter lets `ATEST_RUN_ID` win over config. Merging them is what turns
6
+ * four partial pictures into the run someone actually cares about.
7
+ *
8
+ * Deduplication is by `(testId, project, retry)` rather than by array
9
+ * position: shards can overlap after a re-run, and counting an attempt twice
10
+ * would corrupt every number derived from it.
11
+ */
12
+ import type { AttemptRecord, RunRecord } from '@aplaytest/core';
13
+ export interface MergedRun {
14
+ readonly runId: string;
15
+ readonly startedAt: string;
16
+ readonly finishedAt: string | null;
17
+ readonly commit: string | null;
18
+ readonly branch: string | null;
19
+ readonly ci: boolean;
20
+ readonly shardsMerged: number;
21
+ readonly attempts: readonly AttemptRecord[];
22
+ readonly totals: {
23
+ readonly tests: number;
24
+ readonly passed: number;
25
+ readonly failed: number;
26
+ /** Failed then passed on retry within this run — free flake signal. */
27
+ readonly flaky: number;
28
+ readonly skipped: number;
29
+ readonly durationMs: number;
30
+ };
31
+ }
32
+ export declare function mergeRuns(runs: readonly RunRecord[]): MergedRun | null;
33
+ export declare function formatDuration(ms: number): string;
34
+ //# sourceMappingURL=merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGhE,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IAC5C,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,uEAAuE;QACvE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;KAC7B,CAAC;CACH;AAMD,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,GAAG,IAAI,CA6DtE;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAMjD"}
package/dist/merge.js ADDED
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Merge sharded run records into one view.
3
+ *
4
+ * CI writes one record per shard, all carrying the same run id — that is why
5
+ * the reporter lets `ATEST_RUN_ID` win over config. Merging them is what turns
6
+ * four partial pictures into the run someone actually cares about.
7
+ *
8
+ * Deduplication is by `(testId, project, retry)` rather than by array
9
+ * position: shards can overlap after a re-run, and counting an attempt twice
10
+ * would corrupt every number derived from it.
11
+ */
12
+ import { isFailure } from '@aplaytest/core';
13
+ function attemptKey(attempt) {
14
+ return `${attempt.testId}::${attempt.project}::${attempt.retry}`;
15
+ }
16
+ export function mergeRuns(runs) {
17
+ if (runs.length === 0)
18
+ return null;
19
+ const sorted = [...runs].sort((a, b) => a.startedAt.localeCompare(b.startedAt));
20
+ const first = sorted[0];
21
+ if (first === undefined)
22
+ return null;
23
+ const byKey = new Map();
24
+ for (const run of sorted) {
25
+ for (const attempt of run.attempts)
26
+ byKey.set(attemptKey(attempt), attempt);
27
+ }
28
+ const attempts = [...byKey.values()];
29
+ // Outcome is judged per TEST, not per attempt: a test that failed and then
30
+ // passed on retry is flaky, not failed, and reporting it as failed would
31
+ // make every retried suite look broken.
32
+ const byTest = new Map();
33
+ for (const attempt of attempts) {
34
+ const key = `${attempt.testId}::${attempt.project}`;
35
+ byTest.set(key, [...(byTest.get(key) ?? []), attempt]);
36
+ }
37
+ let passed = 0;
38
+ let failed = 0;
39
+ let flaky = 0;
40
+ let skipped = 0;
41
+ for (const group of byTest.values()) {
42
+ const ordered = [...group].sort((a, b) => a.retry - b.retry);
43
+ const last = ordered[ordered.length - 1];
44
+ if (last === undefined)
45
+ continue;
46
+ if (last.outcome === 'skipped')
47
+ skipped += 1;
48
+ else if (isFailure(last.outcome))
49
+ failed += 1;
50
+ else if (ordered.some(a => isFailure(a.outcome)))
51
+ flaky += 1;
52
+ else
53
+ passed += 1;
54
+ }
55
+ const finished = sorted
56
+ .map(r => r.finishedAt)
57
+ .filter((f) => f !== null)
58
+ .sort();
59
+ return {
60
+ runId: first.runId,
61
+ startedAt: first.startedAt,
62
+ finishedAt: finished[finished.length - 1] ?? null,
63
+ commit: first.commit,
64
+ branch: first.branch,
65
+ ci: first.ci,
66
+ shardsMerged: sorted.length,
67
+ attempts,
68
+ totals: {
69
+ tests: byTest.size,
70
+ passed,
71
+ failed,
72
+ flaky,
73
+ skipped,
74
+ durationMs: attempts.reduce((sum, a) => sum + a.durationMs, 0),
75
+ },
76
+ };
77
+ }
78
+ export function formatDuration(ms) {
79
+ if (ms < 1000)
80
+ return `${ms}ms`;
81
+ if (ms < 60_000)
82
+ return `${(ms / 1000).toFixed(1)}s`;
83
+ const minutes = Math.floor(ms / 60_000);
84
+ const seconds = Math.round((ms % 60_000) / 1000);
85
+ return `${minutes}m ${seconds}s`;
86
+ }
87
+ //# sourceMappingURL=merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.js","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAsB5C,SAAS,UAAU,CAAC,OAAsB;IACxC,OAAO,GAAG,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAA0B;IAClD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEnC,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAChF,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACxB,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAErC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC/C,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACzB,KAAK,MAAM,OAAO,IAAI,GAAG,CAAC,QAAQ;YAAE,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;IAC9E,CAAC;IACD,MAAM,QAAQ,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAErC,2EAA2E;IAC3E,yEAAyE;IACzE,wCAAwC;IACxC,MAAM,MAAM,GAAG,IAAI,GAAG,EAA2B,CAAC;IAClD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC;QACpD,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QAC7D,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACzC,IAAI,IAAI,KAAK,SAAS;YAAE,SAAS;QAEjC,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,CAAC;aACxC,IAAI,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,MAAM,IAAI,CAAC,CAAC;aACzC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YAAE,KAAK,IAAI,CAAC,CAAC;;YACxD,MAAM,IAAI,CAAC,CAAC;IACnB,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM;SACpB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;SACtB,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;SACtC,IAAI,EAAE,CAAC;IAEV,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI;QACjD,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,YAAY,EAAE,MAAM,CAAC,MAAM;QAC3B,QAAQ;QACR,MAAM,EAAE;YACN,KAAK,EAAE,MAAM,CAAC,IAAI;YAClB,MAAM;YACN,MAAM;YACN,KAAK;YACL,OAAO;YACP,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;SAC/D;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,EAAU;IACvC,IAAI,EAAE,GAAG,IAAI;QAAE,OAAO,GAAG,EAAE,IAAI,CAAC;IAChC,IAAI,EAAE,GAAG,MAAM;QAAE,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IACrD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;IACjD,OAAO,GAAG,OAAO,KAAK,OAAO,GAAG,CAAC;AACnC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@aplaytest/report",
3
+ "version": "0.1.0",
4
+ "description": "Shard merge, PR comment, and the self-contained HTML report",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc --build",
14
+ "test": "vitest run"
15
+ },
16
+ "dependencies": {
17
+ "@aplaytest/core": "^0.1.0"
18
+ },
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/index.d.ts",
22
+ "import": "./dist/index.js"
23
+ }
24
+ },
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/ianoflynnautomation/aplaytest.git",
31
+ "directory": "packages/report"
32
+ },
33
+ "homepage": "https://github.com/ianoflynnautomation/aplaytest#readme",
34
+ "bugs": {
35
+ "url": "https://github.com/ianoflynnautomation/aplaytest/issues"
36
+ }
37
+ }