fix: replay reconnect after workspace bootstrap
This commit is contained in:
parent
1a4f930b50
commit
0a4c9a0ae8
|
|
@ -1,5 +1,5 @@
|
||||||
(async function(){
|
(async function(){
|
||||||
await loadWorkspace({ document });
|
const workspaceLifecycle = await loadWorkspace({ document, window });
|
||||||
const qs = (s, el=document) => el.querySelector(s);
|
const qs = (s, el=document) => el.querySelector(s);
|
||||||
const fmt = (d) => new Date(d).toLocaleString();
|
const fmt = (d) => new Date(d).toLocaleString();
|
||||||
const cardPlanning = createCardPlanning(document);
|
const cardPlanning = createCardPlanning(document);
|
||||||
|
|
@ -7389,6 +7389,7 @@
|
||||||
if (!navigator.onLine) await showOfflineStatus();
|
if (!navigator.onLine) await showOfflineStatus();
|
||||||
window.addEventListener('offline', showOfflineStatus);
|
window.addEventListener('offline', showOfflineStatus);
|
||||||
window.addEventListener('online', reconnectOutboxes);
|
window.addEventListener('online', reconnectOutboxes);
|
||||||
|
workspaceLifecycle.replayOnline(reconnectOutboxes);
|
||||||
|
|
||||||
qs('#refresh').addEventListener('click', load);
|
qs('#refresh').addEventListener('click', load);
|
||||||
qs('#plan-today').addEventListener('click', event => openPlanToday(event.currentTarget));
|
qs('#plan-today').addEventListener('click', event => openPlanToday(event.currentTarget));
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
async function loadWorkspace({ document, createLoader = createFeatureLoader }) {
|
async function loadWorkspace({ document, window = null, createLoader = createFeatureLoader }) {
|
||||||
|
let cameOnline = false;
|
||||||
|
let replayed = false;
|
||||||
|
const captureOnline = () => { cameOnline = true; };
|
||||||
|
window?.addEventListener('online', captureOnline);
|
||||||
const status = document.querySelector('#my-work-action-status');
|
const status = document.querySelector('#my-work-action-status');
|
||||||
const url = document.querySelector(
|
const url = document.querySelector(
|
||||||
'meta[name="stackchain-feature-today-timer"]'
|
'meta[name="stackchain-feature-today-timer"]'
|
||||||
|
|
@ -11,7 +15,16 @@ async function loadWorkspace({ document, createLoader = createFeatureLoader }) {
|
||||||
try {
|
try {
|
||||||
await loader.load('today-timer');
|
await loader.load('today-timer');
|
||||||
if (status) status.textContent = '';
|
if (status) status.textContent = '';
|
||||||
|
return {
|
||||||
|
replayOnline(callback) {
|
||||||
|
if (replayed) return;
|
||||||
|
replayed = true;
|
||||||
|
window?.removeEventListener('online', captureOnline);
|
||||||
|
if (cameOnline) callback();
|
||||||
|
},
|
||||||
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
window?.removeEventListener('online', captureOnline);
|
||||||
if (status) {
|
if (status) {
|
||||||
status.textContent =
|
status.textContent =
|
||||||
'Workspace could not load. Check your connection, then reload to retry.';
|
'Workspace could not load. Check your connection, then reload to retry.';
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ FEATURE_SOURCES = {
|
||||||
"security-center": ("static/security-center.js",),
|
"security-center": ("static/security-center.js",),
|
||||||
"today-timer": (
|
"today-timer": (
|
||||||
"static/conversation.js", "static/voice-transcript-store.js", "static/voice-conversation-capture.js", "static/mobile-launch.js", "static/mobile-insights.js", "static/mobile-app-shortcuts.js", "static/mobile-plan-today-nav.js", "static/mobile-find-work-nav.js",
|
"static/conversation.js", "static/voice-transcript-store.js", "static/voice-conversation-capture.js", "static/mobile-launch.js", "static/mobile-insights.js", "static/mobile-app-shortcuts.js", "static/mobile-plan-today-nav.js", "static/mobile-find-work-nav.js",
|
||||||
"static/today-completion.js", "static/card-planning.js", "static/work-detail-position.js", "static/work-route.js", "static/commands.js", "static/saved-searches.js", "static/task-overlay-history.js", "static/search-preview.js", "static/mobile-search-preview-nav.js", "static/search-reply-draft-store.js", "static/conversation-reply-draft-store.js", "static/conversation-photo-drafts.js", "static/search-defer.js", "static/mobile-search-viewport.js", "static/my-work.js", "static/protect-today.js", "static/mobile-task-dock.js", "static/mobile-queue-launcher.js", "static/mobile-start-day.js", "static/update-triage-session.js", "static/update-review-handoff.js", "static/update-triage-launcher.js", "static/update-triage-gesture.js", "static/notification-undo.js", "static/today-timer.js", "static/today-recap.js", "static/today-wrap-up.js", "static/today-handoff.js",
|
"static/today-completion.js", "static/card-planning.js", "static/work-detail-position.js", "static/work-route.js", "static/commands.js", "static/saved-searches.js", "static/task-overlay-history.js", "static/search-preview.js", "static/mobile-search-preview-nav.js", "static/search-reply-draft-store.js", "static/conversation-reply-draft-store.js", "static/conversation-photo-drafts.js", "static/search-defer.js", "static/mobile-search-viewport.js", "static/my-work.js", "static/protect-today.js", "static/mobile-task-dock.js", "static/mobile-work-entry.js", "static/mobile-queue-launcher.js", "static/mobile-start-day.js", "static/update-triage-session.js", "static/update-review-handoff.js", "static/update-triage-launcher.js", "static/update-triage-gesture.js", "static/notification-undo.js", "static/today-timer.js", "static/today-recap.js", "static/today-wrap-up.js", "static/today-handoff.js",
|
||||||
"static/today-rollover.js", "static/later-work.js", "static/later-picker.js", "static/drafts.js", "static/unfiled-captures.js", "static/unfiled-draft-sync.js",
|
"static/today-rollover.js", "static/later-work.js", "static/later-picker.js", "static/drafts.js", "static/unfiled-captures.js", "static/unfiled-draft-sync.js",
|
||||||
"static/assign-and-start.js", "static/filed-claim.js", "static/queue-today.js", "static/create-and-start.js",
|
"static/assign-and-start.js", "static/filed-claim.js", "static/queue-today.js", "static/create-and-start.js",
|
||||||
"static/draft-filing-session.js", "static/draft-capacity-dialog.js", "static/work-selection.js",
|
"static/draft-filing-session.js", "static/draft-capacity-dialog.js", "static/work-selection.js",
|
||||||
|
|
|
||||||
|
|
@ -270,9 +270,8 @@ def test_release_artifact_files_one_mobile_issue_exactly_once_after_offline_relo
|
||||||
context.set_offline(False)
|
context.set_offline(False)
|
||||||
page.evaluate("window.dispatchEvent(new Event('online'))")
|
page.evaluate("window.dispatchEvent(new Event('online'))")
|
||||||
# Containerized Actions runners can take longer than a local browser to wake the
|
# Containerized Actions runners can take longer than a local browser to wake the
|
||||||
# service worker, finish optional workspace activation, and complete its identity
|
# service worker and complete its identity handshake after reconnect.
|
||||||
# handshake after reconnect.
|
for _ in range(160):
|
||||||
for _ in range(240):
|
|
||||||
if fake.created_issues:
|
if fake.created_issues:
|
||||||
break
|
break
|
||||||
page.wait_for_timeout(250)
|
page.wait_for_timeout(250)
|
||||||
|
|
|
||||||
|
|
@ -53,4 +53,26 @@ console.log(JSON.stringify({message,status:status.textContent}));
|
||||||
assert result == {
|
assert result == {
|
||||||
"message": "network failed",
|
"message": "network failed",
|
||||||
"status": "Workspace could not load. Check your connection, then reload to retry.",
|
"status": "Workspace could not load. Check your connection, then reload to retry.",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_workspace_bootstrap_replays_online_event_after_dashboard_registers_handlers():
|
||||||
|
result = run_bootstrap("""
|
||||||
|
const status={textContent:''}; const listeners={};
|
||||||
|
const document={querySelector(selector) {
|
||||||
|
if (selector.startsWith('meta[')) return {content:'feature-workspace-abc.js'};
|
||||||
|
if (selector === '#my-work-action-status') return status;
|
||||||
|
return null;
|
||||||
|
}};
|
||||||
|
const window={
|
||||||
|
addEventListener(name,callback) { listeners[name]=callback; },
|
||||||
|
removeEventListener(name,callback) { if (listeners[name] === callback) delete listeners[name]; },
|
||||||
|
};
|
||||||
|
const createLoader=()=>({load:async()=>{listeners.online();}});
|
||||||
|
const lifecycle=await loadWorkspace({document,window,createLoader});
|
||||||
|
let reconnects=0;
|
||||||
|
lifecycle.replayOnline(()=>{reconnects++;});
|
||||||
|
lifecycle.replayOnline(()=>{reconnects++;});
|
||||||
|
console.log(JSON.stringify({reconnects,listening:Boolean(listeners.online)}));
|
||||||
|
""")
|
||||||
|
assert result == {"reconnects": 1, "listening": False}
|
||||||
Loading…
Reference in New Issue
Block a user