From 4250b557c8438d323fa5378e0c524217855fe9da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Iv=C3=A1n=20Vieitez=20Parra?= <3857362+corrideat@users.noreply.github.com> Date: Wed, 18 Dec 2024 15:34:57 +0000 Subject: [PATCH] Wait for Chelonia, more error logs --- frontend/controller/service-worker.js | 28 +++++++++++++++++++ .../controller/serviceworkers/sw-primary.js | 20 +++++++++++++ frontend/setupChelonia.js | 1 + test/cypress/support/commands.js | 4 +++ 4 files changed, 53 insertions(+) diff --git a/frontend/controller/service-worker.js b/frontend/controller/service-worker.js index 574fa4d42..12866483e 100644 --- a/frontend/controller/service-worker.js +++ b/frontend/controller/service-worker.js @@ -51,6 +51,34 @@ sbp('sbp/selectors/register', { await swRegistration.update() setInterval(() => sbp('service-worker/update'), HOURS_MILLIS) + // Send a 'ready' message to the SW and wait back for a response + // This way we ensure that Chelonia has been set up + await new Promise((resolve, reject) => { + const messageChannel = new MessageChannel() + messageChannel.port1.onmessage = (event) => { + if (event.data.type === 'ready') { + resolve() + } else { + reject(event.data.error) + } + messageChannel.port1.close() + } + messageChannel.port1.onmessageerror = () => { + reject(new Error('Message error')) + messageChannel.port1.close() + } + + navigator.serviceWorker.ready.then((worker) => { + worker.active.postMessage({ + type: 'ready', + port: messageChannel.port2 + }, [messageChannel.port2]) + }).catch((e) => { + reject(e) + messageChannel.port1.close() + }) + }) + // Keep the service worker alive while the window is open // The default idle timeout on Chrome and Firefox is 30 seconds. We send // a ping message every 5 seconds to ensure that the worker remains diff --git a/frontend/controller/serviceworkers/sw-primary.js b/frontend/controller/serviceworkers/sw-primary.js index 3c3f9b83d..c4e3e7910 100644 --- a/frontend/controller/serviceworkers/sw-primary.js +++ b/frontend/controller/serviceworkers/sw-primary.js @@ -244,6 +244,26 @@ self.addEventListener('message', function (event) { case 'event': sbp('okTurtles.events/emit', event.data.subtype, ...deserializer(event.data.data)) break + case 'ready': { + // The 'ready' message is sent by a client (i.e., a tab or window) to + // ensure that Chelonia has been setup + const port = event.data.port + Promise.race([ + setupChelonia(), + new Promise((resolve, reject) => { + setTimeout(() => { + reject(new Error('Timed out setting up Chelonia')) + }, 30e3) + }) + ]).then(() => { + port.postMessage({ type: 'ready' }) + }, (e) => { + port.postMessage({ type: 'error', error: e }) + }).finally(() => { + port.close() + }) + break + } default: console.error('[sw] unknown message type:', event.data) break diff --git a/frontend/setupChelonia.js b/frontend/setupChelonia.js index 625c3880f..4b3971e6b 100644 --- a/frontend/setupChelonia.js +++ b/frontend/setupChelonia.js @@ -310,6 +310,7 @@ export default ((() => { return () => { if (!promise) { promise = setupChelonia().catch((e) => { + console.error('[setupChelonia] Error during chelonia setup', e) promise = undefined // Reset on error throw e // Re-throw the error }) diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index ac9ff7186..c8b2ec87b 100644 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -198,9 +198,13 @@ Cypress.Commands.add('giSignup', (username, { // Wait for the app to be ready cy.getByDT('app').should('have.attr', 'data-ready', 'true') + cy.log('@@@@@@@@@0') cy.window().its('sbp').then(async sbp => { + cy.log('@@@@@@@@@1') await sbp('gi.app/identity/signupAndLogin', { username, password }) + cy.log('@@@@@@@@@2') await sbp('controller/router').push({ path: '/' }).catch(e => {}) + cy.log('@@@@@@@@@3') }) } else { if (!isInvitation) {