@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.
- package/dist/.tsbuildinfo +1 -0
- package/dist/args.d.ts +15 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +47 -0
- package/dist/args.js.map +1 -0
- package/dist/html.d.ts +27 -0
- package/dist/html.d.ts.map +1 -0
- package/dist/html.js +256 -0
- package/dist/html.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/load.d.ts +23 -0
- package/dist/load.d.ts.map +1 -0
- package/dist/load.js +96 -0
- package/dist/load.js.map +1 -0
- package/dist/markdown.d.ts +57 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdown.js +201 -0
- package/dist/markdown.js.map +1 -0
- package/dist/merge.d.ts +34 -0
- package/dist/merge.d.ts.map +1 -0
- package/dist/merge.js +87 -0
- package/dist/merge.js.map +1 -0
- package/package.json +37 -0
|
@@ -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
|
package/dist/args.js.map
ADDED
|
@@ -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, '&')
|
|
29
|
+
.replace(/</g, '<')
|
|
30
|
+
.replace(/>/g, '>')
|
|
31
|
+
.replace(/"/g, '"')
|
|
32
|
+
.replace(/'/g, ''');
|
|
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. “unverified” means no browser
|
|
131
|
+
has resolved it yet — <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">→</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 — 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 —
|
|
249
|
+
no model was consulted to produce it.
|
|
250
|
+
</footer>
|
|
251
|
+
</div>
|
|
252
|
+
</body>
|
|
253
|
+
</html>
|
|
254
|
+
`;
|
|
255
|
+
}
|
|
256
|
+
//# sourceMappingURL=html.js.map
|
package/dist/html.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../src/html.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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
|
package/dist/load.js.map
ADDED
|
@@ -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"}
|
package/dist/markdown.js
ADDED
|
@@ -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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"}
|
package/dist/merge.d.ts
ADDED
|
@@ -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":"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"}
|
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
|
+
}
|