@rehearsal-labs/retest 0.1.0 → 0.2.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/README.md +6 -0
- package/dist/agent/session.d.ts +21 -2
- package/dist/agent/session.d.ts.map +1 -1
- package/dist/agent/session.js +73 -11
- package/dist/api/app-page.d.ts +39 -3
- package/dist/api/app-page.d.ts.map +1 -1
- package/dist/api/app-page.js +108 -0
- package/dist/api/dialog.d.ts +38 -0
- package/dist/api/dialog.d.ts.map +1 -0
- package/dist/api/dialog.js +78 -0
- package/dist/api/drag.d.ts +32 -0
- package/dist/api/drag.d.ts.map +1 -0
- package/dist/api/drag.js +26 -0
- package/dist/api/files.d.ts +49 -0
- package/dist/api/files.d.ts.map +1 -0
- package/dist/api/files.js +168 -0
- package/dist/api/inbox.d.ts +97 -0
- package/dist/api/inbox.d.ts.map +1 -0
- package/dist/api/inbox.js +191 -0
- package/dist/api/locator-recipes.d.ts +1 -1
- package/dist/api/locator-recipes.d.ts.map +1 -1
- package/dist/api/locator-recipes.js +4 -3
- package/dist/api/page.d.ts +214 -4
- package/dist/api/page.d.ts.map +1 -1
- package/dist/api/route.d.ts +21 -0
- package/dist/api/route.d.ts.map +1 -0
- package/dist/api/route.js +99 -0
- package/dist/api/test-run.d.ts +127 -1
- package/dist/api/test-run.d.ts.map +1 -1
- package/dist/api/test-run.js +293 -0
- package/dist/assertions/expect.d.ts +91 -2
- package/dist/assertions/expect.d.ts.map +1 -1
- package/dist/assertions/expect.js +98 -0
- package/dist/assertions/look-until.d.ts +5 -0
- package/dist/assertions/look-until.d.ts.map +1 -1
- package/dist/assertions/look-until.js +1 -1
- package/dist/assertions/poll-layout.d.ts +24 -0
- package/dist/assertions/poll-layout.d.ts.map +1 -0
- package/dist/assertions/poll-layout.js +63 -0
- package/dist/assertions/screenshot.d.ts +36 -0
- package/dist/assertions/screenshot.d.ts.map +1 -0
- package/dist/assertions/screenshot.js +125 -0
- package/dist/browser/accessibility.d.ts.map +1 -1
- package/dist/browser/accessibility.js +22 -1
- package/dist/browser/actionability.d.ts +9 -6
- package/dist/browser/actionability.d.ts.map +1 -1
- package/dist/browser/actionability.js +17 -8
- package/dist/browser/browser.d.ts.map +1 -1
- package/dist/browser/browser.js +15 -4
- package/dist/browser/cdp/connection.d.ts +6 -0
- package/dist/browser/cdp/connection.d.ts.map +1 -1
- package/dist/browser/cdp/connection.js +8 -0
- package/dist/browser/checked-state.d.ts +2 -2
- package/dist/browser/checked-state.d.ts.map +1 -1
- package/dist/browser/chromium-process.d.ts +9 -2
- package/dist/browser/chromium-process.d.ts.map +1 -1
- package/dist/browser/chromium-process.js +17 -4
- package/dist/browser/contract.d.ts +119 -5
- package/dist/browser/contract.d.ts.map +1 -1
- package/dist/browser/dialogs.d.ts +157 -0
- package/dist/browser/dialogs.d.ts.map +1 -0
- package/dist/browser/dialogs.js +271 -0
- package/dist/browser/downloads.d.ts +71 -0
- package/dist/browser/downloads.d.ts.map +1 -0
- package/dist/browser/downloads.js +253 -0
- package/dist/browser/drag.d.ts +50 -0
- package/dist/browser/drag.d.ts.map +1 -0
- package/dist/browser/drag.js +584 -0
- package/dist/browser/electron-window-watch.d.ts +32 -0
- package/dist/browser/electron-window-watch.d.ts.map +1 -0
- package/dist/browser/electron-window-watch.js +93 -0
- package/dist/browser/electron.d.ts +13 -2
- package/dist/browser/electron.d.ts.map +1 -1
- package/dist/browser/electron.js +53 -8
- package/dist/browser/element-queries.d.ts +51 -15
- package/dist/browser/element-queries.d.ts.map +1 -1
- package/dist/browser/element-queries.js +92 -13
- package/dist/browser/emulation.d.ts.map +1 -1
- package/dist/browser/emulation.js +7 -5
- package/dist/browser/file-chooser.d.ts +75 -0
- package/dist/browser/file-chooser.d.ts.map +1 -0
- package/dist/browser/file-chooser.js +449 -0
- package/dist/browser/firefox/input.d.ts +5 -0
- package/dist/browser/firefox/input.d.ts.map +1 -1
- package/dist/browser/firefox/input.js +6 -3
- package/dist/browser/firefox/page.d.ts +11 -1
- package/dist/browser/firefox/page.d.ts.map +1 -1
- package/dist/browser/firefox/page.js +66 -7
- package/dist/browser/frames.d.ts +205 -0
- package/dist/browser/frames.d.ts.map +1 -0
- package/dist/browser/frames.js +657 -0
- package/dist/browser/input-guard.d.ts +18 -5
- package/dist/browser/input-guard.d.ts.map +1 -1
- package/dist/browser/input-guard.js +65 -6
- package/dist/browser/isolated-world.d.ts +8 -1
- package/dist/browser/isolated-world.d.ts.map +1 -1
- package/dist/browser/layout.d.ts +120 -0
- package/dist/browser/layout.d.ts.map +1 -0
- package/dist/browser/layout.js +213 -0
- package/dist/browser/locate.d.ts +10 -0
- package/dist/browser/locate.d.ts.map +1 -1
- package/dist/browser/locate.js +24 -6
- package/dist/browser/origin-document.d.ts +4 -0
- package/dist/browser/origin-document.d.ts.map +1 -1
- package/dist/browser/origin-document.js +9 -1
- package/dist/browser/page-scripts.d.ts +48 -0
- package/dist/browser/page-scripts.d.ts.map +1 -1
- package/dist/browser/page-scripts.js +515 -39
- package/dist/browser/page.d.ts +60 -1
- package/dist/browser/page.d.ts.map +1 -1
- package/dist/browser/page.js +275 -32
- package/dist/browser/popups.d.ts +166 -0
- package/dist/browser/popups.d.ts.map +1 -0
- package/dist/browser/popups.js +317 -0
- package/dist/browser/routes.d.ts +97 -0
- package/dist/browser/routes.d.ts.map +1 -0
- package/dist/browser/routes.js +226 -0
- package/dist/browser/screenshot.d.ts +44 -0
- package/dist/browser/screenshot.d.ts.map +1 -0
- package/dist/browser/screenshot.js +51 -0
- package/dist/browser/shadow-candidates.d.ts +20 -0
- package/dist/browser/shadow-candidates.d.ts.map +1 -0
- package/dist/browser/shadow-candidates.js +77 -0
- package/dist/browser/webkit/page.d.ts +11 -1
- package/dist/browser/webkit/page.d.ts.map +1 -1
- package/dist/browser/webkit/page.js +53 -2
- package/dist/browser/webkit/relay.d.ts.map +1 -1
- package/dist/browser/webkit/relay.js +5 -1
- package/dist/cli/commands/run.d.ts.map +1 -1
- package/dist/cli/commands/run.js +2 -0
- package/dist/cli/inspect/test-timeline.d.ts.map +1 -1
- package/dist/cli/inspect/test-timeline.js +38 -4
- package/dist/config/loaded.d.ts +12 -2
- package/dist/config/loaded.d.ts.map +1 -1
- package/dist/config/read-inboxes.d.ts +10 -0
- package/dist/config/read-inboxes.d.ts.map +1 -0
- package/dist/config/read-inboxes.js +78 -0
- package/dist/config/register.d.ts +5 -1
- package/dist/config/register.d.ts.map +1 -1
- package/dist/config/types.d.ts +36 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/validate.d.ts.map +1 -1
- package/dist/config/validate.js +4 -1
- package/dist/diagnostics/artifact.d.ts.map +1 -1
- package/dist/diagnostics/artifact.js +10 -2
- package/dist/diagnostics/attempt.d.ts +5 -0
- package/dist/diagnostics/attempt.d.ts.map +1 -1
- package/dist/diagnostics/attempt.js +10 -0
- package/dist/diagnostics/chromium-collector.d.ts +9 -1
- package/dist/diagnostics/chromium-collector.d.ts.map +1 -1
- package/dist/diagnostics/chromium-collector.js +19 -4
- package/dist/diagnostics/observations.d.ts +8 -0
- package/dist/diagnostics/observations.d.ts.map +1 -1
- package/dist/diagnostics/session-capture.d.ts.map +1 -1
- package/dist/diagnostics/session-capture.js +8 -0
- package/dist/index.d.ts +9 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/media/policy.d.ts +2 -2
- package/dist/media/policy.d.ts.map +1 -1
- package/dist/media/policy.js +1 -1
- package/dist/playwright/not-yet.d.ts.map +1 -1
- package/dist/playwright/not-yet.js +5 -2
- package/dist/protocol/commands.d.ts +122 -13
- package/dist/protocol/commands.d.ts.map +1 -1
- package/dist/protocol/commands.js +85 -6
- package/dist/protocol/diagnostics.d.ts +10 -0
- package/dist/protocol/diagnostics.d.ts.map +1 -1
- package/dist/protocol/diagnostics.js +5 -0
- package/dist/protocol/dialogs.d.ts +104 -0
- package/dist/protocol/dialogs.d.ts.map +1 -0
- package/dist/protocol/dialogs.js +101 -0
- package/dist/protocol/drag.d.ts +45 -0
- package/dist/protocol/drag.d.ts.map +1 -0
- package/dist/protocol/drag.js +31 -0
- package/dist/protocol/events.d.ts +153 -1
- package/dist/protocol/events.d.ts.map +1 -1
- package/dist/protocol/events.js +97 -0
- package/dist/protocol/files.d.ts +83 -0
- package/dist/protocol/files.d.ts.map +1 -0
- package/dist/protocol/files.js +68 -0
- package/dist/protocol/inbox.d.ts +87 -0
- package/dist/protocol/inbox.d.ts.map +1 -0
- package/dist/protocol/inbox.js +51 -0
- package/dist/protocol/index.d.ts +4 -1
- package/dist/protocol/index.d.ts.map +1 -1
- package/dist/protocol/layout-checks.d.ts +83 -0
- package/dist/protocol/layout-checks.d.ts.map +1 -0
- package/dist/protocol/layout-checks.js +214 -0
- package/dist/protocol/layout.d.ts +135 -0
- package/dist/protocol/layout.d.ts.map +1 -0
- package/dist/protocol/layout.js +124 -0
- package/dist/protocol/locator-checks.d.ts +19 -2
- package/dist/protocol/locator-checks.d.ts.map +1 -1
- package/dist/protocol/locator-checks.js +23 -1
- package/dist/protocol/locator.d.ts +55 -7
- package/dist/protocol/locator.d.ts.map +1 -1
- package/dist/protocol/locator.js +99 -18
- package/dist/protocol/messages.d.ts +95 -0
- package/dist/protocol/messages.d.ts.map +1 -1
- package/dist/protocol/messages.js +63 -0
- package/dist/protocol/popups.d.ts +43 -0
- package/dist/protocol/popups.d.ts.map +1 -0
- package/dist/protocol/popups.js +27 -0
- package/dist/protocol/result.d.ts +5 -0
- package/dist/protocol/result.d.ts.map +1 -1
- package/dist/protocol/result.js +1 -0
- package/dist/protocol/routes.d.ts +136 -0
- package/dist/protocol/routes.d.ts.map +1 -0
- package/dist/protocol/routes.js +191 -0
- package/dist/protocol/screenshot.d.ts +219 -0
- package/dist/protocol/screenshot.d.ts.map +1 -0
- package/dist/protocol/screenshot.js +335 -0
- package/dist/reporters/actions.d.ts +6 -4
- package/dist/reporters/actions.d.ts.map +1 -1
- package/dist/reporters/actions.js +24 -6
- package/dist/reporters/agent.d.ts.map +1 -1
- package/dist/reporters/agent.js +4 -2
- package/dist/reporters/dialogs-popups.d.ts +22 -0
- package/dist/reporters/dialogs-popups.d.ts.map +1 -0
- package/dist/reporters/dialogs-popups.js +30 -0
- package/dist/reporters/failure-card.d.ts +10 -1
- package/dist/reporters/failure-card.d.ts.map +1 -1
- package/dist/reporters/failure-card.js +5 -1
- package/dist/reporters/format.d.ts +33 -0
- package/dist/reporters/format.d.ts.map +1 -1
- package/dist/reporters/format.js +42 -0
- package/dist/reporters/html/comparison-view.d.ts +12 -0
- package/dist/reporters/html/comparison-view.d.ts.map +1 -0
- package/dist/reporters/html/comparison-view.js +21 -0
- package/dist/reporters/html/diagnostics-view.js +8 -0
- package/dist/reporters/html/downloads-view.d.ts +10 -0
- package/dist/reporters/html/downloads-view.d.ts.map +1 -0
- package/dist/reporters/html/downloads-view.js +29 -0
- package/dist/reporters/html/style.d.ts.map +1 -1
- package/dist/reporters/html/style.js +3 -0
- package/dist/reporters/html/summary-view.d.ts.map +1 -1
- package/dist/reporters/html/summary-view.js +3 -2
- package/dist/reporters/html/test-view.d.ts.map +1 -1
- package/dist/reporters/html/test-view.js +6 -3
- package/dist/reporters/html/timeline-view.d.ts.map +1 -1
- package/dist/reporters/html/timeline-view.js +26 -2
- package/dist/reporters/human-card.js +10 -0
- package/dist/reporters/human.d.ts.map +1 -1
- package/dist/reporters/human.js +3 -1
- package/dist/reporters/routes.d.ts +9 -0
- package/dist/reporters/routes.d.ts.map +1 -0
- package/dist/reporters/routes.js +17 -0
- package/dist/runner/child-program.js +10 -0
- package/dist/runner/contract.d.ts +5 -0
- package/dist/runner/contract.d.ts.map +1 -1
- package/dist/runner/dialogs.d.ts +71 -0
- package/dist/runner/dialogs.d.ts.map +1 -0
- package/dist/runner/dialogs.js +189 -0
- package/dist/runner/files.d.ts +79 -0
- package/dist/runner/files.d.ts.map +1 -0
- package/dist/runner/files.js +312 -0
- package/dist/runner/inbox-links.d.ts +19 -0
- package/dist/runner/inbox-links.d.ts.map +1 -0
- package/dist/runner/inbox-links.js +63 -0
- package/dist/runner/inbox.d.ts +87 -0
- package/dist/runner/inbox.d.ts.map +1 -0
- package/dist/runner/inbox.js +340 -0
- package/dist/runner/index.d.ts +2 -1
- package/dist/runner/index.d.ts.map +1 -1
- package/dist/runner/native-pool.d.ts.map +1 -1
- package/dist/runner/native-pool.js +2 -0
- package/dist/runner/observations.d.ts +15 -2
- package/dist/runner/observations.d.ts.map +1 -1
- package/dist/runner/observations.js +109 -6
- package/dist/runner/popups.d.ts +82 -0
- package/dist/runner/popups.d.ts.map +1 -0
- package/dist/runner/popups.js +236 -0
- package/dist/runner/redactor.d.ts.map +1 -1
- package/dist/runner/redactor.js +10 -6
- package/dist/runner/routes.d.ts +23 -0
- package/dist/runner/routes.d.ts.map +1 -0
- package/dist/runner/routes.js +128 -0
- package/dist/runner/run-media.d.ts +6 -0
- package/dist/runner/run-media.d.ts.map +1 -1
- package/dist/runner/run-media.js +21 -0
- package/dist/runner/run-session.d.ts.map +1 -1
- package/dist/runner/run-session.js +93 -8
- package/dist/runner/running-test.d.ts +35 -0
- package/dist/runner/running-test.d.ts.map +1 -1
- package/dist/runner/running-test.js +333 -22
- package/dist/runner/screenshot-baselines.d.ts +159 -0
- package/dist/runner/screenshot-baselines.d.ts.map +1 -0
- package/dist/runner/screenshot-baselines.js +357 -0
- package/dist/runner/secrets.d.ts +13 -0
- package/dist/runner/secrets.d.ts.map +1 -1
- package/dist/runner/secrets.js +6 -4
- package/dist/runner/test-pages.d.ts +3 -1
- package/dist/runner/test-pages.d.ts.map +1 -1
- package/dist/runner/test-pages.js +4 -3
- package/dist/schemas/event-v1.schema.json +118873 -6311
- package/dist/schemas/result-v1.schema.json +4 -0
- package/dist/shared/image-diff.d.ts +36 -0
- package/dist/shared/image-diff.d.ts.map +1 -0
- package/dist/shared/image-diff.js +242 -0
- package/dist/shared/metadata-process.d.ts +4 -1
- package/dist/shared/metadata-process.d.ts.map +1 -1
- package/dist/shared/metadata-process.js +51 -9
- package/dist/shared/png.d.ts +35 -0
- package/dist/shared/png.d.ts.map +1 -0
- package/dist/shared/png.js +251 -0
- package/dist/shared/process-ownership.d.ts +15 -4
- package/dist/shared/process-ownership.d.ts.map +1 -1
- package/dist/shared/process-ownership.js +123 -34
- package/dist/store/artifacts.d.ts +23 -2
- package/dist/store/artifacts.d.ts.map +1 -1
- package/dist/store/artifacts.js +40 -1
- package/dist/store/rebuild-result.d.ts.map +1 -1
- package/dist/store/rebuild-result.js +6 -0
- package/package.json +1 -1
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { isTokenSegment } from "../diagnostics/sanitize.js";
|
|
2
|
+
// A parameter whose name is one of these words, or a longer word ending in one, as `access_token` or `oobCode` read,
|
|
3
|
+
// carries a credential, whatever its value looks like.
|
|
4
|
+
const credentialWords = ['token', 'code', 'key', 'secret', 'signature', 'sig', 'auth', 'otp', 'nonce', 'ticket', 'session', 'hash', 'password'];
|
|
5
|
+
/**
|
|
6
|
+
* Reads a link from a message, or undefined when its address is not an http or https URL. A password in the address is
|
|
7
|
+
* a token. A part reads as a token when it is one of the message's codes; when it is a query parameter, or a parameter of a fragment written as a query,
|
|
8
|
+
* whose name speaks of a credential; or when it reads as one as diagnostics read a path segment: 16 letters and digits
|
|
9
|
+
* or more, 12 digits or more, or a JSON Web Token's shape, and not a file name, a version or a date. That rule applies
|
|
10
|
+
* to each path segment, each query value and the fragment.
|
|
11
|
+
*
|
|
12
|
+
* @example readLink('https://app.test/verify/9f8e7d6c5b4a39281706f5e4?utm=mail', [])?.tokens // ['9f8e7d6c5b4a39281706f5e4']
|
|
13
|
+
*/
|
|
14
|
+
export function readLink(address, codes) {
|
|
15
|
+
const url = URL.parse(address.trim());
|
|
16
|
+
if (url === null || (url.protocol !== 'http:' && url.protocol !== 'https:'))
|
|
17
|
+
return undefined;
|
|
18
|
+
const isCode = (value) => codes.includes(value);
|
|
19
|
+
// A password written into the address is a credential, whatever it looks like.
|
|
20
|
+
const found = url.password === '' ? [] : [url.password, decoded(url.password)];
|
|
21
|
+
for (const segment of url.pathname.split('/')) {
|
|
22
|
+
if (segment !== '' && (isCode(decoded(segment)) || isTokenSegment(segment)))
|
|
23
|
+
found.push(segment, decoded(segment));
|
|
24
|
+
}
|
|
25
|
+
found.push(...parameterTokens(url.search.slice(1), isCode));
|
|
26
|
+
// A fragment written as a query, as a sign-in that hands its token to the page writes it, is read as one.
|
|
27
|
+
const fragment = url.hash.slice(1);
|
|
28
|
+
if (fragment.includes('='))
|
|
29
|
+
found.push(...parameterTokens(fragment, isCode));
|
|
30
|
+
else if (fragment !== '' && (isCode(decoded(fragment)) || isTokenSegment(fragment)))
|
|
31
|
+
found.push(fragment, decoded(fragment));
|
|
32
|
+
return { url, tokens: [...new Set(found.filter((part) => part !== ''))] };
|
|
33
|
+
}
|
|
34
|
+
// Each parameter's value, raw and decoded, when its name speaks of a credential or its value reads as a token.
|
|
35
|
+
function parameterTokens(query, isCode) {
|
|
36
|
+
const found = [];
|
|
37
|
+
for (const pair of query.split('&')) {
|
|
38
|
+
const separator = pair.indexOf('=');
|
|
39
|
+
if (separator === -1)
|
|
40
|
+
continue;
|
|
41
|
+
const name = decoded(pair.slice(0, separator).replaceAll('+', ' '));
|
|
42
|
+
const raw = pair.slice(separator + 1);
|
|
43
|
+
const value = decoded(raw.replaceAll('+', ' '));
|
|
44
|
+
if (value !== '' && (namesCredential(name) || isCode(value) || isTokenSegment(raw)))
|
|
45
|
+
found.push(raw, value);
|
|
46
|
+
}
|
|
47
|
+
return found;
|
|
48
|
+
}
|
|
49
|
+
function namesCredential(name) {
|
|
50
|
+
const words = name
|
|
51
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1 $2')
|
|
52
|
+
.toLowerCase()
|
|
53
|
+
.split(/[^a-z0-9]+/);
|
|
54
|
+
return words.some((word) => credentialWords.some((credential) => word.endsWith(credential)));
|
|
55
|
+
}
|
|
56
|
+
function decoded(text) {
|
|
57
|
+
try {
|
|
58
|
+
return decodeURIComponent(text);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return text;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { LoadedInbox } from '../config/loaded.ts';
|
|
2
|
+
import type { Failure } from '../protocol/failures.ts';
|
|
3
|
+
import type { InboxAnswer, InboxCodeRef, InboxLinkRef, InboxRequest } from '../protocol/inbox.ts';
|
|
4
|
+
import type { LocatorRecipe } from '../protocol/locator.ts';
|
|
5
|
+
import type { Redactor } from './redactor.ts';
|
|
6
|
+
import type { FillContext, FillResolution } from './secrets.ts';
|
|
7
|
+
/** How long a read may look, and the signal that stops it, as when its test is stopped. */
|
|
8
|
+
export type InboxReadBudget = {
|
|
9
|
+
readonly timeoutMs: number;
|
|
10
|
+
readonly signal: AbortSignal;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* How a read ended, as its event records it: the answer for the test, how many messages the mailbox held on the last
|
|
14
|
+
* look, how many times Retest asked it, and how long the read took.
|
|
15
|
+
*/
|
|
16
|
+
export type InboxRead = {
|
|
17
|
+
readonly answer: InboxAnswer;
|
|
18
|
+
readonly messages: number;
|
|
19
|
+
readonly looks: number;
|
|
20
|
+
readonly waitedMs: number;
|
|
21
|
+
};
|
|
22
|
+
/** A code fill as the test file's process sends it: the code by its message and number, never its value. */
|
|
23
|
+
export type InboxCodeFill = {
|
|
24
|
+
kind: 'fill';
|
|
25
|
+
locator: LocatorRecipe;
|
|
26
|
+
value: InboxCodeRef;
|
|
27
|
+
};
|
|
28
|
+
/** Where a link from an inbox may open: the origins of the base URLs of the test's apps. */
|
|
29
|
+
export type LinkContext = {
|
|
30
|
+
readonly appOrigins: readonly string[];
|
|
31
|
+
};
|
|
32
|
+
/** A link resolved to its address, or why it may not open. */
|
|
33
|
+
export type LinkResolution = {
|
|
34
|
+
ok: true;
|
|
35
|
+
url: string;
|
|
36
|
+
} | {
|
|
37
|
+
ok: false;
|
|
38
|
+
failure: Failure;
|
|
39
|
+
};
|
|
40
|
+
export type AttemptInboxOptions = {
|
|
41
|
+
readonly inboxes: ReadonlyMap<string, LoadedInbox>;
|
|
42
|
+
readonly redactor: Redactor;
|
|
43
|
+
/** When the attempt started, in milliseconds since 1970. A message received before then is not the test's. */
|
|
44
|
+
readonly startedAt: number;
|
|
45
|
+
};
|
|
46
|
+
/** A message as the source gave it, once its shape is checked, with when it arrived in milliseconds since 1970. */
|
|
47
|
+
type SourceMessage = {
|
|
48
|
+
readonly subject: string;
|
|
49
|
+
readonly from: string;
|
|
50
|
+
readonly text: string;
|
|
51
|
+
readonly codes: readonly string[];
|
|
52
|
+
readonly links: readonly {
|
|
53
|
+
readonly url: string;
|
|
54
|
+
readonly text: string;
|
|
55
|
+
}[];
|
|
56
|
+
readonly receivedAt: number;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* One attempt's reads of the run's inboxes. Each read asks the mailbox again until a message arrives that was received
|
|
60
|
+
* since the attempt started, and since the last message the attempt was given from that inbox, and that has the
|
|
61
|
+
* subject the test asked for, or until its time runs out. Every code and every token in a link that a mailbox gives is
|
|
62
|
+
* taught to the redactor as it arrives, whether or not the test is given that message. The test's process receives the
|
|
63
|
+
* message with its codes and those links replaced by placeholders, and names a code or a link by its message and number;
|
|
64
|
+
* only this process reads the values, and binds them to origins as it binds a secret.
|
|
65
|
+
*/
|
|
66
|
+
export declare class AttemptInbox {
|
|
67
|
+
#private;
|
|
68
|
+
constructor({ inboxes, redactor, startedAt }: AttemptInboxOptions);
|
|
69
|
+
/** Reads an inbox for the test, looking again until a message arrives or the read's time runs out. */
|
|
70
|
+
read(request: InboxRequest, { timeoutMs, signal }: InboxReadBudget): Promise<InboxRead>;
|
|
71
|
+
/**
|
|
72
|
+
* Turns a fill of a code into the text the page types, bound to the origins the code may be typed on: those of the
|
|
73
|
+
* test's apps' base URLs and the inbox's own, or on an Electron app's window only the inbox's. A native app takes none.
|
|
74
|
+
*/
|
|
75
|
+
resolveCode(command: InboxCodeFill, context: FillContext): Promise<FillResolution>;
|
|
76
|
+
/** Turns a link into the address the page opens, when its origin is one of the test's apps' or the inbox's own. */
|
|
77
|
+
resolveLink(reference: InboxLinkRef, { appOrigins }: LinkContext): LinkResolution;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Checks what an inbox's function gave: a list of messages, each with a subject, a sender and text, a list of codes, a
|
|
81
|
+
* list of links of `{ url, text }`, and when it arrived. A problem names the message and the field, never a value.
|
|
82
|
+
*
|
|
83
|
+
* @example checkMessages([{ subject: 'Hi' }]) // 'message 1 has no from'
|
|
84
|
+
*/
|
|
85
|
+
export declare function checkMessages(value: unknown): SourceMessage[] | string;
|
|
86
|
+
export {};
|
|
87
|
+
//# sourceMappingURL=inbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../../src/runner/inbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import { waitBeforeRead } from "../assertions/wait-before-read.js";
|
|
2
|
+
import { matchesText } from "../browser/text-match.js";
|
|
3
|
+
import { Deadline, elapsedMs, monotonicClock } from "../protocol/deadline.js";
|
|
4
|
+
import { errorMessage, failure, failureSchema } from "../protocol/failures.js";
|
|
5
|
+
import { codePlaceholderName, describeInboxReference, linkName, linkPlaceholder } from "../protocol/inbox.js";
|
|
6
|
+
import { describeTextMatch, patternProblem } from "../protocol/locator.js";
|
|
7
|
+
import { isArray, isPlainObject, parse } from "../protocol/schema.js";
|
|
8
|
+
import { originOf } from "../protocol/url.js";
|
|
9
|
+
import { bounded } from "./bounded.js";
|
|
10
|
+
import { readLink } from "./inbox-links.js";
|
|
11
|
+
import { locateFill } from "./secrets.js";
|
|
12
|
+
/** The shortest code Retest hides safely, as for a secret. */
|
|
13
|
+
const minCodeLength = 4;
|
|
14
|
+
// How long a read waits between looks: a mailbox is a service of its own, asked more gently than a page.
|
|
15
|
+
const pauses = [100, 250, 500, 1000];
|
|
16
|
+
/**
|
|
17
|
+
* One attempt's reads of the run's inboxes. Each read asks the mailbox again until a message arrives that was received
|
|
18
|
+
* since the attempt started, and since the last message the attempt was given from that inbox, and that has the
|
|
19
|
+
* subject the test asked for, or until its time runs out. Every code and every token in a link that a mailbox gives is
|
|
20
|
+
* taught to the redactor as it arrives, whether or not the test is given that message. The test's process receives the
|
|
21
|
+
* message with its codes and those links replaced by placeholders, and names a code or a link by its message and number;
|
|
22
|
+
* only this process reads the values, and binds them to origins as it binds a secret.
|
|
23
|
+
*/
|
|
24
|
+
export class AttemptInbox {
|
|
25
|
+
#inboxes;
|
|
26
|
+
#redactor;
|
|
27
|
+
#startedAt;
|
|
28
|
+
#given = new Map();
|
|
29
|
+
#histories = new Map();
|
|
30
|
+
constructor({ inboxes, redactor, startedAt }) {
|
|
31
|
+
this.#inboxes = inboxes;
|
|
32
|
+
this.#redactor = redactor;
|
|
33
|
+
this.#startedAt = startedAt;
|
|
34
|
+
}
|
|
35
|
+
/** Reads an inbox for the test, looking again until a message arrives or the read's time runs out. */
|
|
36
|
+
async read(request, { timeoutMs, signal }) {
|
|
37
|
+
const startedAt = monotonicClock();
|
|
38
|
+
const ended = (answer, messages, looks) => ({ answer, messages, looks, waitedMs: elapsedMs(startedAt) });
|
|
39
|
+
const inbox = this.#inboxes.get(request.inbox);
|
|
40
|
+
if (inbox === undefined)
|
|
41
|
+
return ended({ ok: false, failure: unknownInbox(request.inbox, [...this.#inboxes.keys()]) }, 0, 0);
|
|
42
|
+
const problem = subjectProblem(request.subject);
|
|
43
|
+
if (problem !== undefined)
|
|
44
|
+
return ended({ ok: false, failure: problem }, 0, 0);
|
|
45
|
+
const deadline = new Deadline(timeoutMs, { signal });
|
|
46
|
+
const history = this.#history(request.inbox);
|
|
47
|
+
let looks = 0;
|
|
48
|
+
let held = [];
|
|
49
|
+
let fresh = [];
|
|
50
|
+
let answered = false;
|
|
51
|
+
for (;;) {
|
|
52
|
+
looks += 1;
|
|
53
|
+
const look = await this.#look(request.inbox, inbox, deadline, signal);
|
|
54
|
+
if (look.kind === 'failed')
|
|
55
|
+
return ended({ ok: false, failure: look.failure }, held.length, looks);
|
|
56
|
+
if (look.kind === 'messages') {
|
|
57
|
+
answered = true;
|
|
58
|
+
held = look.messages;
|
|
59
|
+
fresh = this.#fresh(held, history);
|
|
60
|
+
const chosen = fresh.find((message) => request.subject === undefined || matchesText(this.#hidden(message, message.subject), request.subject, false));
|
|
61
|
+
if (chosen !== undefined)
|
|
62
|
+
return ended(this.#give(request.inbox, chosen, history), held.length, looks);
|
|
63
|
+
}
|
|
64
|
+
const last = look.kind === 'timed_out' ? (answered ? 'unanswered' : 'silent') : 'answered';
|
|
65
|
+
if (deadline.reached)
|
|
66
|
+
return ended({ ok: false, failure: this.#nothingArrived({ request, looks, held, fresh, timeoutMs, last }) }, held.length, looks);
|
|
67
|
+
try {
|
|
68
|
+
await waitBeforeRead(deadline, pauses[Math.min(looks, pauses.length) - 1] ?? 1000);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
if (!signal.aborted)
|
|
72
|
+
throw error;
|
|
73
|
+
return ended({ ok: false, failure: stopped(request.inbox, signal.reason) }, held.length, looks);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Turns a fill of a code into the text the page types, bound to the origins the code may be typed on: those of the
|
|
79
|
+
* test's apps' base URLs and the inbox's own, or on an Electron app's window only the inbox's. A native app takes none.
|
|
80
|
+
*/
|
|
81
|
+
async resolveCode(command, context) {
|
|
82
|
+
const reference = command.value;
|
|
83
|
+
const given = this.#given.get(reference.message);
|
|
84
|
+
const inbox = this.#inboxes.get(reference.inbox);
|
|
85
|
+
if (given === undefined || given.inbox !== reference.inbox || inbox === undefined)
|
|
86
|
+
return refused('usage', notGiven('code', reference.inbox));
|
|
87
|
+
const code = given.codes[reference.code - 1];
|
|
88
|
+
if (code === undefined)
|
|
89
|
+
return refused('usage', `The message ${JSON.stringify(given.subject)} from the inbox ${JSON.stringify(reference.inbox)} holds no code, so Retest typed nothing.`);
|
|
90
|
+
if (context.bundleId !== undefined)
|
|
91
|
+
return refused('unsupported', `Retest types a code from an inbox only into a web page, and typed nothing into ${context.bundleId}.`, { bundleId: context.bundleId });
|
|
92
|
+
const electron = context.target === 'electron';
|
|
93
|
+
const allowedOrigins = electron ? [...inbox.origins] : [...new Set([...context.appOrigins, ...inbox.origins])];
|
|
94
|
+
const located = await locateFill(context);
|
|
95
|
+
if (located.kind === 'stopped')
|
|
96
|
+
return { ok: false, failure: stoppedFill(reference.inbox, context.signal.reason) };
|
|
97
|
+
const web = originOf(located.pageUrl);
|
|
98
|
+
if (web === undefined || !allowedOrigins.includes(web)) {
|
|
99
|
+
return refused('not_actionable', wrongCodeOrigin({ inbox: reference.inbox, origin: web, allowed: allowedOrigins, electron }), { origin: web ?? null });
|
|
100
|
+
}
|
|
101
|
+
return { ok: true, command: { kind: 'fill', locator: command.locator, value: code, secret: codePlaceholderName, allowedOrigins } };
|
|
102
|
+
}
|
|
103
|
+
/** Turns a link into the address the page opens, when its origin is one of the test's apps' or the inbox's own. */
|
|
104
|
+
resolveLink(reference, { appOrigins }) {
|
|
105
|
+
const given = this.#given.get(reference.message);
|
|
106
|
+
const inbox = this.#inboxes.get(reference.inbox);
|
|
107
|
+
if (given === undefined || given.inbox !== reference.inbox || inbox === undefined)
|
|
108
|
+
return refusedLink('usage', notGiven('link', reference.inbox));
|
|
109
|
+
const shown = describeInboxReference(reference);
|
|
110
|
+
if (reference.link > given.links.length) {
|
|
111
|
+
return refusedLink('usage', `The message ${JSON.stringify(given.subject)} from the inbox ${JSON.stringify(reference.inbox)} holds no link ${reference.link}, so Retest opened nothing.`);
|
|
112
|
+
}
|
|
113
|
+
const link = given.links[reference.link - 1];
|
|
114
|
+
if (link === undefined)
|
|
115
|
+
return refusedLink('unsupported', `${shown} from the inbox ${JSON.stringify(reference.inbox)} is not an http or https address, so Retest opened nothing.`);
|
|
116
|
+
const allowed = [...new Set([...appOrigins, ...inbox.origins])];
|
|
117
|
+
const { origin } = link.url;
|
|
118
|
+
if (!allowed.includes(origin)) {
|
|
119
|
+
const permitted = allowed.length === 0 ? 'no origin, since no app the test uses has a base URL and the inbox lists no origins' : allowed.join(', ');
|
|
120
|
+
const message = `Retest did not open ${shown} from the inbox ${JSON.stringify(reference.inbox)}: it goes to ${origin}, and a link from this inbox may open only on ${permitted}. Add the origin to the inbox's origins if it belongs there.`;
|
|
121
|
+
return { ok: false, failure: { ...failure('not_actionable', message), details: { origin } } };
|
|
122
|
+
}
|
|
123
|
+
return { ok: true, url: link.url.href };
|
|
124
|
+
}
|
|
125
|
+
#history(inbox) {
|
|
126
|
+
const known = this.#histories.get(inbox);
|
|
127
|
+
if (known !== undefined)
|
|
128
|
+
return known;
|
|
129
|
+
const history = { receivedAt: this.#startedAt, given: new Set() };
|
|
130
|
+
this.#histories.set(inbox, history);
|
|
131
|
+
return history;
|
|
132
|
+
}
|
|
133
|
+
// One look at the mailbox, within the read's time. The function is told through its signal when Retest stops waiting.
|
|
134
|
+
// Whatever it gives is taught to the redactor as it arrives, even after the read stopped waiting for it, since the app
|
|
135
|
+
// may show it next.
|
|
136
|
+
async #look(name, inbox, deadline, signal) {
|
|
137
|
+
const waiting = new AbortController();
|
|
138
|
+
const stop = Promise.withResolvers();
|
|
139
|
+
const onAbort = () => stop.resolve();
|
|
140
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
141
|
+
if (signal.aborted)
|
|
142
|
+
onAbort();
|
|
143
|
+
const reading = inbox.read({ signal: waiting.signal });
|
|
144
|
+
void reading.then((value) => this.#learn(value), () => undefined);
|
|
145
|
+
const read = await bounded(reading, deadline.commandTimeoutMs, stop.promise);
|
|
146
|
+
signal.removeEventListener('abort', onAbort);
|
|
147
|
+
if (read.status === 'stopped') {
|
|
148
|
+
waiting.abort(new DOMException(`Retest stopped reading the inbox ${JSON.stringify(name)}: its read was stopped.`, 'AbortError'));
|
|
149
|
+
return { kind: 'failed', failure: stopped(name, signal.reason) };
|
|
150
|
+
}
|
|
151
|
+
if (read.status === 'timed_out') {
|
|
152
|
+
waiting.abort(new DOMException(`Retest stopped reading the inbox ${JSON.stringify(name)}: it took longer than ${deadline.budgetMs} ms.`, 'TimeoutError'));
|
|
153
|
+
return { kind: 'timed_out' };
|
|
154
|
+
}
|
|
155
|
+
if (read.status === 'failed')
|
|
156
|
+
return { kind: 'failed', failure: failure('setup_failed', `Retest could not read the inbox ${JSON.stringify(name)}: ${this.#redactor.redact(errorMessage(read.error))}`) };
|
|
157
|
+
const checked = checkMessages(read.value);
|
|
158
|
+
if (typeof checked === 'string')
|
|
159
|
+
return { kind: 'failed', failure: failure('setup_failed', `The inbox ${JSON.stringify(name)} gave messages Retest cannot read: ${checked}.`) };
|
|
160
|
+
return { kind: 'messages', messages: checked };
|
|
161
|
+
}
|
|
162
|
+
// Each token of each link is hidden as its link's placeholder, and each code as `{{code}}`, which is learned last so a
|
|
163
|
+
// code a link carries reads as the code. Only text long enough to hide safely is learned.
|
|
164
|
+
#learn(value) {
|
|
165
|
+
if (!isArray(value))
|
|
166
|
+
return;
|
|
167
|
+
for (const message of value) {
|
|
168
|
+
if (!isPlainObject(message))
|
|
169
|
+
continue;
|
|
170
|
+
const codes = isArray(message['codes']) ? message['codes'].filter((code) => typeof code === 'string') : [];
|
|
171
|
+
const links = isArray(message['links']) ? message['links'] : [];
|
|
172
|
+
for (const [index, link] of links.entries()) {
|
|
173
|
+
const url = isPlainObject(link) ? link['url'] : undefined;
|
|
174
|
+
const read = typeof url === 'string' ? readLink(url, codes) : undefined;
|
|
175
|
+
for (const token of read?.tokens ?? [])
|
|
176
|
+
if (token.length >= minCodeLength)
|
|
177
|
+
this.#redactor.learn(linkName(index + 1), token);
|
|
178
|
+
}
|
|
179
|
+
for (const code of codes)
|
|
180
|
+
if (code.length >= minCodeLength)
|
|
181
|
+
this.#redactor.learn(codePlaceholderName, code);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// The messages received since the attempt started, and since the last one it was given from this inbox, that it was
|
|
185
|
+
// not given already, newest first. Two messages received at the same moment keep the mailbox's order.
|
|
186
|
+
#fresh(messages, history) {
|
|
187
|
+
const fresh = messages.filter((message) => message.receivedAt >= history.receivedAt && !history.given.has(fingerprint(message)));
|
|
188
|
+
return fresh.toSorted((first, second) => second.receivedAt - first.receivedAt);
|
|
189
|
+
}
|
|
190
|
+
#give(inbox, message, history) {
|
|
191
|
+
const short = message.codes.find((code) => code.length < minCodeLength);
|
|
192
|
+
if (short !== undefined) {
|
|
193
|
+
return { ok: false, failure: failure('setup_failed', `The inbox ${JSON.stringify(inbox)} gave a message with a code shorter than ${minCodeLength} characters, too short to redact safely, so Retest gave the test nothing.`) };
|
|
194
|
+
}
|
|
195
|
+
history.given.add(fingerprint(message));
|
|
196
|
+
history.receivedAt = Math.max(history.receivedAt, message.receivedAt);
|
|
197
|
+
const id = `m${this.#given.size + 1}`;
|
|
198
|
+
const reads = message.links.map((link) => readLink(link.url, message.codes));
|
|
199
|
+
const subject = this.#hidden(message, message.subject);
|
|
200
|
+
this.#given.set(id, { inbox, subject, codes: message.codes, links: reads });
|
|
201
|
+
const links = message.links.map((link, index) => {
|
|
202
|
+
const read = reads[index];
|
|
203
|
+
const text = this.#hidden(message, link.text);
|
|
204
|
+
if (read === undefined)
|
|
205
|
+
return { text, origin: '', path: '', token: false };
|
|
206
|
+
return { text, origin: read.url.origin, path: this.#redactor.redact(read.url.pathname), token: read.tokens.length > 0 };
|
|
207
|
+
});
|
|
208
|
+
const record = {
|
|
209
|
+
id,
|
|
210
|
+
inbox,
|
|
211
|
+
subject,
|
|
212
|
+
from: this.#hidden(message, message.from),
|
|
213
|
+
text: this.#hidden(message, message.text),
|
|
214
|
+
codes: message.codes.length,
|
|
215
|
+
links,
|
|
216
|
+
receivedAt: new Date(message.receivedAt).toISOString(),
|
|
217
|
+
};
|
|
218
|
+
return { ok: true, message: record };
|
|
219
|
+
}
|
|
220
|
+
// Text of a message as the test reads it: each link that carries a token, written whole, replaced by its placeholder,
|
|
221
|
+
// and then every value the run hides, the message's codes and the tokens of its links among them.
|
|
222
|
+
#hidden(message, text) {
|
|
223
|
+
const whole = message.links.flatMap((link, index) => {
|
|
224
|
+
const read = readLink(link.url, message.codes);
|
|
225
|
+
if (read === undefined || read.tokens.length === 0)
|
|
226
|
+
return [];
|
|
227
|
+
return [...new Set([link.url.trim(), read.url.href])].map((written) => ({ written, placeholder: linkPlaceholder(index + 1) }));
|
|
228
|
+
});
|
|
229
|
+
whole.sort((first, second) => second.written.length - first.written.length);
|
|
230
|
+
let replaced = text;
|
|
231
|
+
for (const { written, placeholder } of whole)
|
|
232
|
+
replaced = replaced.replaceAll(written, placeholder);
|
|
233
|
+
return this.#redactor.redact(replaced);
|
|
234
|
+
}
|
|
235
|
+
#nothingArrived({ request, looks, held, fresh, timeoutMs, last }) {
|
|
236
|
+
const history = this.#histories.get(request.inbox);
|
|
237
|
+
const since = history !== undefined && history.given.size > 0 ? 'since the last message this test was given' : 'since the test started';
|
|
238
|
+
const wanted = request.subject === undefined ? '' : `, and none of them has a subject matching ${describeTextMatch(request.subject)}`;
|
|
239
|
+
const holding = held.length === 0 ? 'the inbox held no message' : `the inbox held ${count(held.length, 'message')}, ${fresh.length === 0 ? 'none' : String(fresh.length)} received ${since}${fresh.length === 0 ? '' : wanted}`;
|
|
240
|
+
const seen = last === 'answered' ? `On the last look, ${holding}.`
|
|
241
|
+
: last === 'silent' ? 'The inbox gave no answer in that time.'
|
|
242
|
+
: `The last look got no answer in the time left. On the last look that answered, ${holding}.`;
|
|
243
|
+
const message = `No message arrived in the inbox ${JSON.stringify(request.inbox)} within ${timeoutMs} ms. Retest looked ${count(looks, 'time')}. ${seen}`;
|
|
244
|
+
return { ...failure('timeout', message), details: { inbox: request.inbox, looks, messages: held.length, fresh: fresh.length, timeoutMs } };
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Checks what an inbox's function gave: a list of messages, each with a subject, a sender and text, a list of codes, a
|
|
249
|
+
* list of links of `{ url, text }`, and when it arrived. A problem names the message and the field, never a value.
|
|
250
|
+
*
|
|
251
|
+
* @example checkMessages([{ subject: 'Hi' }]) // 'message 1 has no from'
|
|
252
|
+
*/
|
|
253
|
+
export function checkMessages(value) {
|
|
254
|
+
if (!isArray(value))
|
|
255
|
+
return `expected a list of messages, received ${kindOf(value)}`;
|
|
256
|
+
const messages = [];
|
|
257
|
+
for (const [index, message] of value.entries()) {
|
|
258
|
+
const which = `message ${index + 1}`;
|
|
259
|
+
if (!isPlainObject(message))
|
|
260
|
+
return `${which} is ${kindOf(message)}, not an object`;
|
|
261
|
+
const { subject, from, text, codes, links, receivedAt } = message;
|
|
262
|
+
if (typeof subject !== 'string')
|
|
263
|
+
return fieldProblem(which, 'subject', subject);
|
|
264
|
+
if (typeof from !== 'string')
|
|
265
|
+
return fieldProblem(which, 'from', from);
|
|
266
|
+
if (typeof text !== 'string')
|
|
267
|
+
return fieldProblem(which, 'text', text);
|
|
268
|
+
if (!isArray(codes) || codes.some((code) => typeof code !== 'string' || code === ''))
|
|
269
|
+
return `${which} has codes that are not a list of text`;
|
|
270
|
+
const checkedLinks = [];
|
|
271
|
+
if (!isArray(links))
|
|
272
|
+
return `${which} has links that are not a list`;
|
|
273
|
+
for (const [place, link] of links.entries()) {
|
|
274
|
+
if (!isPlainObject(link) || typeof link['url'] !== 'string' || typeof link['text'] !== 'string')
|
|
275
|
+
return `link ${place + 1} of ${which} is not { url, text }`;
|
|
276
|
+
checkedLinks.push({ url: link['url'], text: link['text'] });
|
|
277
|
+
}
|
|
278
|
+
const time = timeOf(receivedAt);
|
|
279
|
+
if (time === undefined)
|
|
280
|
+
return `${which} has no receivedAt that reads as a time`;
|
|
281
|
+
messages.push({ subject, from, text, codes: codes.filter((code) => typeof code === 'string'), links: checkedLinks, receivedAt: time });
|
|
282
|
+
}
|
|
283
|
+
return messages;
|
|
284
|
+
}
|
|
285
|
+
function fieldProblem(which, key, field) {
|
|
286
|
+
return field === undefined ? `${which} has no ${key}` : `${which} has a ${key} that is ${kindOf(field)}, not text`;
|
|
287
|
+
}
|
|
288
|
+
function timeOf(value) {
|
|
289
|
+
const time = value instanceof Date ? value.getTime() : typeof value === 'number' ? value : typeof value === 'string' ? Date.parse(value) : Number.NaN;
|
|
290
|
+
return Number.isFinite(time) ? time : undefined;
|
|
291
|
+
}
|
|
292
|
+
// What a message holds, as the attempt tells two messages apart: two alike in every field are one message.
|
|
293
|
+
function fingerprint(message) {
|
|
294
|
+
return JSON.stringify([message.receivedAt, message.subject, message.from, message.text, message.codes, message.links]);
|
|
295
|
+
}
|
|
296
|
+
function unknownInbox(name, declared) {
|
|
297
|
+
const known = declared.length === 0 ? 'This run has no inboxes.' : `The config's inboxes are ${declared.map((each) => JSON.stringify(each)).join(', ')}.`;
|
|
298
|
+
return failure('usage', `inbox(${JSON.stringify(name)}) is not one of the config's inboxes. ${known}`);
|
|
299
|
+
}
|
|
300
|
+
function subjectProblem(subject) {
|
|
301
|
+
if (subject === undefined || typeof subject === 'string')
|
|
302
|
+
return undefined;
|
|
303
|
+
const problem = patternProblem(subject);
|
|
304
|
+
return problem === undefined ? undefined : failure('usage', `latest() received a subject RegExp Retest cannot read: ${problem}.`);
|
|
305
|
+
}
|
|
306
|
+
function notGiven(what, inbox) {
|
|
307
|
+
return `This ${what} belongs to no message the inbox ${JSON.stringify(inbox)} gave this test, so Retest ${what === 'code' ? 'typed' : 'opened'} nothing.`;
|
|
308
|
+
}
|
|
309
|
+
// A read stopped while it waited ends as the reason it was stopped says.
|
|
310
|
+
function stopped(inbox, reason) {
|
|
311
|
+
const parsed = parse(failureSchema, reason);
|
|
312
|
+
const cause = parsed.ok ? parsed.value : failure('interrupted', 'The read was stopped.');
|
|
313
|
+
return { ...cause, message: `${cause.message} Retest stopped reading the inbox ${JSON.stringify(inbox)}.` };
|
|
314
|
+
}
|
|
315
|
+
function stoppedFill(inbox, reason) {
|
|
316
|
+
const parsed = parse(failureSchema, reason);
|
|
317
|
+
const cause = parsed.ok ? parsed.value : failure('interrupted', 'The fill was stopped.');
|
|
318
|
+
const message = `${cause.message} Retest stopped waiting for the page to open an address for the code from the inbox ${JSON.stringify(inbox)}, and typed nothing.`;
|
|
319
|
+
return { class: cause.class, message, details: { ...cause.details, inputSent: false } };
|
|
320
|
+
}
|
|
321
|
+
function wrongCodeOrigin({ inbox, origin, allowed, electron }) {
|
|
322
|
+
const where = origin === undefined ? 'the page has not opened a web address yet' : `the page is on ${origin}`;
|
|
323
|
+
const none = electron ? 'no origin, since in an Electron app only the inbox\'s origins count and it lists none' : 'no origin, since no app the test uses has a base URL and the inbox lists no origins';
|
|
324
|
+
const permitted = allowed.length === 0 ? none : allowed.join(', ');
|
|
325
|
+
return `Retest did not type the code from the inbox ${JSON.stringify(inbox)}: ${where}, and it may be typed only on ${permitted}. Add the origin to the inbox's origins if it belongs there.`;
|
|
326
|
+
}
|
|
327
|
+
function refused(kind, message, details) {
|
|
328
|
+
return { ok: false, failure: { ...failure(kind, message), ...(details === undefined ? {} : { details }) } };
|
|
329
|
+
}
|
|
330
|
+
function refusedLink(kind, message) {
|
|
331
|
+
return { ok: false, failure: failure(kind, message) };
|
|
332
|
+
}
|
|
333
|
+
function count(amount, noun) {
|
|
334
|
+
return `${amount} ${noun}${amount === 1 ? '' : 's'}`;
|
|
335
|
+
}
|
|
336
|
+
function kindOf(value) {
|
|
337
|
+
if (value === null)
|
|
338
|
+
return 'null';
|
|
339
|
+
return Array.isArray(value) ? 'an array' : typeof value;
|
|
340
|
+
}
|
package/dist/runner/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { LaunchError } from '../browser/contract.ts';
|
|
2
2
|
export type { BrowserCommand, ContextCapability, DispatchedCommand, DriverName, InputDispatch, LaunchOptions, NativeKind, NavigationCapability, NewPageOptions, ObservationScope, OwnedBrowser, OwnedPage, PageNavigation, PageReading, ProxyOptions, ResolvedFill, RuntimeIdentity, Session, SessionIdentity, SessionOwner, SessionRuntime, StorageStateCapability, TargetKind, TextQuery, WebEngine, WebRuntime, WebRuntimeIdentity, WebSession, } from '../browser/contract.ts';
|
|
3
|
-
export type { LoadedConfig } from '../config/loaded.ts';
|
|
3
|
+
export type { LoadedConfig, LoadedInbox } from '../config/loaded.ts';
|
|
4
|
+
export type { InboxContext, InboxMessage, InboxMessageLink, InboxReader, InboxSource } from '../config/types.ts';
|
|
4
5
|
export { defaultTimeouts, mergeTimeouts } from '../protocol/timeouts.ts';
|
|
5
6
|
export type { Timeouts } from '../protocol/timeouts.ts';
|
|
6
7
|
export { validateConfig } from '../config/validate.ts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACpD,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,aAAa,EACb,UAAU,EACV,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACT,cAAc,EACd,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,OAAO,EACP,eAAe,EACf,YAAY,EACZ,cAAc,EACd,sBAAsB,EACtB,UAAU,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,kBAAkB,EAClB,UAAU,GACX,MAAM,wBAAwB,CAAA;AAC/B,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACpD,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,aAAa,EACb,UAAU,EACV,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACT,cAAc,EACd,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,OAAO,EACP,eAAe,EACf,YAAY,EACZ,cAAc,EACd,sBAAsB,EACtB,UAAU,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,kBAAkB,EAClB,UAAU,GACX,MAAM,wBAAwB,CAAA;AAC/B,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACpE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChH,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AACxE,YAAY,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACzD,YAAY,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACxD,YAAY,EACV,cAAc,EACd,WAAW,EACX,cAAc,EACd,aAAa,EACb,cAAc,EACd,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,QAAQ,EACR,SAAS,EACT,cAAc,EACd,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,cAAc,EACd,OAAO,EACP,UAAU,EACV,SAAS,EACT,aAAa,EACb,cAAc,EACd,SAAS,EACT,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,aAAa,GACd,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AACjE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AACnD,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAC/E,YAAY,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-pool.d.ts","sourceRoot":"","sources":["../../src/runner/native-pool.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"native-pool.d.ts","sourceRoot":"","sources":["../../src/runner/native-pool.ts"],"names":[],"mappings":"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"}
|
|
@@ -336,6 +336,8 @@ export class NativePageAdapter {
|
|
|
336
336
|
return unsupported(`Retest typed no secret into ${this.bundleId}: a secret reaches a native app only after Retest has checked that secretOrigins names its bundle id.`);
|
|
337
337
|
return (await this.native.dispatch(command, timeoutMs, signal)).result;
|
|
338
338
|
}
|
|
339
|
+
if (command.kind === 'observeLayout')
|
|
340
|
+
return unsupported('Layout matchers measure a web page, and a native app has no page layout to measure, so Retest measured nothing.');
|
|
339
341
|
return unsupported(`${command.kind} is a web capability and is not available on a native app.`);
|
|
340
342
|
}
|
|
341
343
|
capture(timeoutMs) { return this.native.capture(timeoutMs); }
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type { Observation, PageObservation } from '../protocol/commands.ts';
|
|
2
2
|
import type { ChildEvent, EventBody } from '../protocol/events.ts';
|
|
3
3
|
import type { Failure } from '../protocol/failures.ts';
|
|
4
|
+
import type { LayoutLook } from '../protocol/layout.ts';
|
|
5
|
+
import type { LayoutRequest } from '../protocol/layout-checks.ts';
|
|
4
6
|
import type { CheckRecord, PageLook } from '../protocol/locator-checks.ts';
|
|
5
7
|
import type { LocatorRecipe } from '../protocol/locator.ts';
|
|
8
|
+
import type { ScreenshotLook, ScreenshotRequest } from '../protocol/screenshot.ts';
|
|
6
9
|
import type { Redactor } from './redactor.ts';
|
|
7
10
|
/** A page as an event records it: its origin and path, and its title when it has one. */
|
|
8
11
|
export type PageFields = {
|
|
@@ -12,7 +15,7 @@ export type PageFields = {
|
|
|
12
15
|
/**
|
|
13
16
|
* A look the parent served: the app and locator it read, the session that served it, the observation as sent,
|
|
14
17
|
* redacted and whole, and the page it read, as the look itself read it. A look at the page itself holds what it saw
|
|
15
|
-
* of the page, as sent, and the app's base URL.
|
|
18
|
+
* of the page, as sent, and the app's base URL. A layout look holds what it was asked to measure and what it measured.
|
|
16
19
|
*/
|
|
17
20
|
export type ServedObservation = (PageFields & {
|
|
18
21
|
app: string;
|
|
@@ -23,7 +26,17 @@ export type ServedObservation = (PageFields & {
|
|
|
23
26
|
app: string;
|
|
24
27
|
sessionId: string;
|
|
25
28
|
page: PageLook;
|
|
26
|
-
}
|
|
29
|
+
} | (PageFields & {
|
|
30
|
+
app: string;
|
|
31
|
+
sessionId: string;
|
|
32
|
+
request: LayoutRequest;
|
|
33
|
+
layout: LayoutLook;
|
|
34
|
+
}) | (PageFields & {
|
|
35
|
+
app: string;
|
|
36
|
+
sessionId: string;
|
|
37
|
+
picture: ScreenshotRequest;
|
|
38
|
+
screenshot: ScreenshotLook;
|
|
39
|
+
});
|
|
27
40
|
/**
|
|
28
41
|
* Where an assertion looked, as the parent knows it: its app, the session of that app's page in this attempt, and the
|
|
29
42
|
* document the parent last saw that page commit, with its title when it has one.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observations.d.ts","sourceRoot":"","sources":["../../src/runner/observations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAC3E,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAClE,OAAO,KAAK,EAAE,OAAO,EAAiB,MAAM,yBAAyB,CAAA;AACrE,OAAO,KAAK,EAAE,WAAW,EAAuC,QAAQ,EAAE,MAAM,+BAA+B,CAAA;AAC/G,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"observations.d.ts","sourceRoot":"","sources":["../../src/runner/observations.ts"],"names":[],"mappings":"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"}
|