@le-space/playwright 0.8.0 → 0.9.1
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/index.d.ts +17 -1
- package/index.js +51 -15
- package/package.json +3 -3
package/index.d.ts
CHANGED
|
@@ -316,6 +316,22 @@ declare function waitForAlephMessageForgotten(options: {
|
|
|
316
316
|
pollIntervalMs?: number;
|
|
317
317
|
fetch?: typeof fetch;
|
|
318
318
|
}): Promise<string>;
|
|
319
|
+
/**
|
|
320
|
+
* The address that published `messageHash`, or `null` when no replica will say.
|
|
321
|
+
*
|
|
322
|
+
* Aleph only honours a FORGET signed by a message's original sender, so this is
|
|
323
|
+
* what decides whether a cleanup account has any power over a message at all.
|
|
324
|
+
*
|
|
325
|
+
* `null` means "could not be read" — never "not owned". Callers must treat the
|
|
326
|
+
* two differently: an unreadable sender is a transient API problem, and turning
|
|
327
|
+
* it into a hard failure would make cleanup flaky for reasons unrelated to the
|
|
328
|
+
* relay being cleaned up.
|
|
329
|
+
*/
|
|
330
|
+
declare function resolveAlephMessageSender(options: {
|
|
331
|
+
messageHash: string;
|
|
332
|
+
apiHosts?: readonly string[];
|
|
333
|
+
fetch?: typeof fetch;
|
|
334
|
+
}): Promise<string | null>;
|
|
319
335
|
declare function cleanupRelay(options: CleanupRelayOptions): Promise<CleanupRelayResult>;
|
|
320
336
|
declare function createRelayEvidence(options: {
|
|
321
337
|
instanceName: string;
|
|
@@ -334,4 +350,4 @@ declare function createRelayTest(options: CreateRelayTestOptions): _playwright_t
|
|
|
334
350
|
relayLifecycle: RelayLifecycleFixture;
|
|
335
351
|
}, _playwright_test.PlaywrightWorkerArgs & _playwright_test.PlaywrightWorkerOptions>;
|
|
336
352
|
|
|
337
|
-
export { type AlephChromiumConnector, type AlephCostEvidence, type AlephCreditBalanceSnapshot, type AlephPricingSnapshot, type AlephRemoteBrowserOptions, type AlephRunnerInstanceCandidate, type AlephRunnerJanitorSelection, type CleanupRelayHooks, type CleanupRelayOptions, type CleanupRelayResult, type CreateRelayTestOptions, DEFAULT_ALEPH_SCHEDULER_URL, type ForwardBrowserConsoleOptions, LIBP2P_DIAGNOSTIC_CONSOLE_FILTER, PLAYWRIGHT_RUNNER_VERSION, type ProgressLogger, type ProvisionRelayOptions, type ProvisionedRelay, type RelayAddressPolicy, RelayButtonDriver, type RelayButtonDriverOptions, type RelayEvidence, type RelayEvidenceStep, type RelayLifecycleFixture, type RelayWalletAccount, SUPPORTED_ALEPH_API_HOSTS, type WaitForPubsubSubscriberOptions, appendRelayGithubSummary, buildAlephCostEvidence, cleanupRelay, connectAlephChromium, createProgressLogger, createRelayEvidence, createRelayTest, findAlephInstanceHash, formatAlephCostGithubSummary, formatRelayGithubSummary, forwardBrowserConsole, installEip1193WalletMock, provisionRelay, resolveAlephApiHosts, selectBrowserRelayAddresses, selectExpiredAlephPlaywrightRunners, updateRelayEvidenceStep, waitForAlephInstanceDeletion, waitForAlephMessageForgotten, waitForBootstrapRegistration, waitForDeployableManifest, waitForPubsubSubscriber, writeRelayEvidence };
|
|
353
|
+
export { type AlephChromiumConnector, type AlephCostEvidence, type AlephCreditBalanceSnapshot, type AlephPricingSnapshot, type AlephRemoteBrowserOptions, type AlephRunnerInstanceCandidate, type AlephRunnerJanitorSelection, type CleanupRelayHooks, type CleanupRelayOptions, type CleanupRelayResult, type CreateRelayTestOptions, DEFAULT_ALEPH_SCHEDULER_URL, type ForwardBrowserConsoleOptions, LIBP2P_DIAGNOSTIC_CONSOLE_FILTER, PLAYWRIGHT_RUNNER_VERSION, type ProgressLogger, type ProvisionRelayOptions, type ProvisionedRelay, type RelayAddressPolicy, RelayButtonDriver, type RelayButtonDriverOptions, type RelayEvidence, type RelayEvidenceStep, type RelayLifecycleFixture, type RelayWalletAccount, SUPPORTED_ALEPH_API_HOSTS, type WaitForPubsubSubscriberOptions, appendRelayGithubSummary, buildAlephCostEvidence, cleanupRelay, connectAlephChromium, createProgressLogger, createRelayEvidence, createRelayTest, findAlephInstanceHash, formatAlephCostGithubSummary, formatRelayGithubSummary, forwardBrowserConsole, installEip1193WalletMock, provisionRelay, resolveAlephApiHosts, resolveAlephMessageSender, selectBrowserRelayAddresses, selectExpiredAlephPlaywrightRunners, updateRelayEvidenceStep, waitForAlephInstanceDeletion, waitForAlephMessageForgotten, waitForBootstrapRegistration, waitForDeployableManifest, waitForPubsubSubscriber, writeRelayEvidence };
|
package/index.js
CHANGED
|
@@ -573,6 +573,22 @@ async function waitForAlephMessageForgotten(options) {
|
|
|
573
573
|
`Aleph bootstrap registration ${options.messageHash} was not deregistered within ${options.timeoutMs ?? 2 * 6e4}ms: ${lastSummary}`
|
|
574
574
|
);
|
|
575
575
|
}
|
|
576
|
+
async function resolveAlephMessageSender(options) {
|
|
577
|
+
const fetchImpl = options.fetch ?? globalThis.fetch?.bind(globalThis);
|
|
578
|
+
if (!fetchImpl) throw new Error("A fetch implementation is required to resolve a message sender");
|
|
579
|
+
for (const apiHost of resolveAlephApiHosts(options.apiHosts)) {
|
|
580
|
+
try {
|
|
581
|
+
const response = await fetchImpl(new URL(`/api/v0/messages/${options.messageHash}`, apiHost), {
|
|
582
|
+
cache: "no-cache"
|
|
583
|
+
});
|
|
584
|
+
const payload = await response.json().catch(() => null);
|
|
585
|
+
const sender = payload?.message?.sender;
|
|
586
|
+
if (typeof sender === "string" && sender.length > 0) return sender;
|
|
587
|
+
} catch {
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
return null;
|
|
591
|
+
}
|
|
576
592
|
async function cleanupRelay(options) {
|
|
577
593
|
if (!/^[a-f0-9]{64}$/iu.test(options.instanceHash)) {
|
|
578
594
|
throw new Error(`Invalid Aleph INSTANCE hash: ${options.instanceHash}`);
|
|
@@ -585,6 +601,35 @@ async function cleanupRelay(options) {
|
|
|
585
601
|
const forget = options.hooks?.forget ?? forgetAlephMessages;
|
|
586
602
|
const hosts = resolveAlephApiHosts(options.apiHosts);
|
|
587
603
|
let uiDeleteRequested = false;
|
|
604
|
+
let ownership;
|
|
605
|
+
const resolveRegistrationOwnership = async () => {
|
|
606
|
+
if (!ownership) {
|
|
607
|
+
const sender = options.registrationHash ? await resolveAlephMessageSender({
|
|
608
|
+
messageHash: options.registrationHash,
|
|
609
|
+
apiHosts: hosts,
|
|
610
|
+
fetch: fetchImpl
|
|
611
|
+
}) : null;
|
|
612
|
+
ownership = {
|
|
613
|
+
owned: sender !== null && sender.toLowerCase() === options.account.address.toLowerCase(),
|
|
614
|
+
sender
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
return ownership;
|
|
618
|
+
};
|
|
619
|
+
const verifyRegistrationDeregistered = async () => {
|
|
620
|
+
if (!options.registrationHash) return void 0;
|
|
621
|
+
const { owned, sender } = await resolveRegistrationOwnership();
|
|
622
|
+
if (!owned) {
|
|
623
|
+
return sender === null ? `Bootstrap registration ${options.registrationHash} was not awaited: its sender could not be read from any Aleph replica.` : `Bootstrap registration ${options.registrationHash} was not awaited: it belongs to ${sender}, not the cleanup account ${options.account.address}, so only the relay itself can deregister it.`;
|
|
624
|
+
}
|
|
625
|
+
return waitForAlephMessageForgotten({
|
|
626
|
+
messageHash: options.registrationHash,
|
|
627
|
+
apiHosts: hosts,
|
|
628
|
+
timeoutMs: options.timeoutMs,
|
|
629
|
+
pollIntervalMs: options.pollIntervalMs,
|
|
630
|
+
fetch: fetchImpl
|
|
631
|
+
});
|
|
632
|
+
};
|
|
588
633
|
try {
|
|
589
634
|
await driver.requestDelete(options.instanceName);
|
|
590
635
|
uiDeleteRequested = true;
|
|
@@ -600,13 +645,7 @@ async function cleanupRelay(options) {
|
|
|
600
645
|
pollIntervalMs: options.pollIntervalMs,
|
|
601
646
|
fetch: fetchImpl
|
|
602
647
|
});
|
|
603
|
-
const registrationVerificationSummary2 =
|
|
604
|
-
messageHash: options.registrationHash,
|
|
605
|
-
apiHosts: hosts,
|
|
606
|
-
timeoutMs: options.timeoutMs,
|
|
607
|
-
pollIntervalMs: options.pollIntervalMs,
|
|
608
|
-
fetch: fetchImpl
|
|
609
|
-
}) : void 0;
|
|
648
|
+
const registrationVerificationSummary2 = await verifyRegistrationDeregistered();
|
|
610
649
|
return {
|
|
611
650
|
instanceHash: options.instanceHash,
|
|
612
651
|
uiDeleteRequested,
|
|
@@ -644,11 +683,13 @@ async function cleanupRelay(options) {
|
|
|
644
683
|
const hasher = (content) => createHash("sha256").update(content).digest("hex");
|
|
645
684
|
let forgetSummary = "";
|
|
646
685
|
let lastForgetError = "No Aleph API host attempted.";
|
|
686
|
+
const { owned: registrationOwned } = await resolveRegistrationOwnership();
|
|
687
|
+
const forgetHashes = registrationOwned && options.registrationHash ? [options.instanceHash, options.registrationHash] : [options.instanceHash];
|
|
647
688
|
for (const apiHost of hosts) {
|
|
648
689
|
try {
|
|
649
690
|
const result = await forget({
|
|
650
691
|
sender: options.account.address,
|
|
651
|
-
hashes:
|
|
692
|
+
hashes: forgetHashes,
|
|
652
693
|
reason: "Relay Button Playwright cleanup",
|
|
653
694
|
signer,
|
|
654
695
|
hasher,
|
|
@@ -676,13 +717,7 @@ async function cleanupRelay(options) {
|
|
|
676
717
|
pollIntervalMs: options.pollIntervalMs,
|
|
677
718
|
fetch: fetchImpl
|
|
678
719
|
});
|
|
679
|
-
const registrationVerificationSummary =
|
|
680
|
-
messageHash: options.registrationHash,
|
|
681
|
-
apiHosts: hosts,
|
|
682
|
-
timeoutMs: options.timeoutMs,
|
|
683
|
-
pollIntervalMs: options.pollIntervalMs,
|
|
684
|
-
fetch: fetchImpl
|
|
685
|
-
}) : void 0;
|
|
720
|
+
const registrationVerificationSummary = await verifyRegistrationDeregistered();
|
|
686
721
|
return {
|
|
687
722
|
instanceHash: options.instanceHash,
|
|
688
723
|
uiDeleteRequested,
|
|
@@ -845,6 +880,7 @@ export {
|
|
|
845
880
|
installEip1193WalletMock,
|
|
846
881
|
provisionRelay,
|
|
847
882
|
resolveAlephApiHosts,
|
|
883
|
+
resolveAlephMessageSender,
|
|
848
884
|
selectBrowserRelayAddresses,
|
|
849
885
|
selectExpiredAlephPlaywrightRunners,
|
|
850
886
|
updateRelayEvidenceStep,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@le-space/playwright",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Reusable Playwright fixtures and Relay Button lifecycle helpers.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"url": "https://github.com/NiKrause/relay-button/issues"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@le-space/aleph-bootstrap": "0.
|
|
31
|
-
"@le-space/core": "0.
|
|
30
|
+
"@le-space/aleph-bootstrap": "0.9.1",
|
|
31
|
+
"@le-space/core": "0.9.1"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"@playwright/test": ">=1.61.1 <1.62.0"
|