fix: finish identity recovery before workspace readiness
This commit is contained in:
1 parent
5ccf499b1a
commit
02b9fdd2e4
6 files changed
+111
-8
No files matched your search
@@ -60,6 +60,7 @@ def test_release_artifact_guides_an_empty_mobile_account_to_first_work(
|
||||
expect(sheet).to_be_hidden()
|
||||
expect(page.locator("#find-work-sheet")).to_be_visible()
|
||||
page.locator("#close-find-work").click()
|
||||
expect(page.locator("#find-work-sheet")).to_be_hidden()
|
||||
|
||||
context.set_offline(True)
|
||||
page.locator('[data-mobile-task="work"]').click()
|
||||
@@ -70,8 +71,9 @@ def test_release_artifact_guides_an_empty_mobile_account_to_first_work(
|
||||
expect(page.locator("#mobile-first-task-create")).to_be_focused()
|
||||
|
||||
page.locator("#close-mobile-first-task").click()
|
||||
expect(sheet).to_be_hidden()
|
||||
context.set_offline(False)
|
||||
page.evaluate(
|
||||
probe_result = page.evaluate(
|
||||
"""() => {
|
||||
document.querySelector('[data-mobile-today-hud]').hidden = false;
|
||||
localStorage.setItem('stackchain.first-task.v1:timmy', 'coaching');
|
||||
@@ -82,17 +84,54 @@ def test_release_artifact_guides_an_empty_mobile_account_to_first_work(
|
||||
getLogin: () => 'timmy', hasWork: () => true, isTodayActive: () => true,
|
||||
coach: isolatedCoach,
|
||||
});
|
||||
return window.firstTaskOutcomeProbe.refresh();
|
||||
return {
|
||||
result: window.firstTaskOutcomeProbe.refresh(),
|
||||
state: localStorage.getItem('stackchain.first-task.v1:timmy'),
|
||||
mobile: matchMedia('(max-width: 600px)').matches,
|
||||
};
|
||||
}"""
|
||||
)
|
||||
assert probe_result == {"result": "coaching", "state": "coaching", "mobile": True}
|
||||
coach = page.locator("[data-mobile-first-task-coach]")
|
||||
expect(coach).to_be_visible()
|
||||
try:
|
||||
expect(coach).to_be_visible()
|
||||
except AssertionError as error:
|
||||
raise AssertionError(page.evaluate("""() => {
|
||||
const coach = document.querySelector('[data-mobile-first-task-coach]');
|
||||
const hud = coach.closest('[data-mobile-today-hud]');
|
||||
return {
|
||||
coachHidden: coach.hidden,
|
||||
coachDisplay: getComputedStyle(coach).display,
|
||||
hudHidden: hud.hidden,
|
||||
hudOverlay: hud.getAttribute('data-overlay-hidden'),
|
||||
hudDisplay: getComputedStyle(hud).display,
|
||||
open: Array.from(document.querySelectorAll('dialog, .open'))
|
||||
.filter(element => element.open || element.classList.contains('open'))
|
||||
.map(element => element.id || element.className),
|
||||
};
|
||||
}""")) from error
|
||||
expect(coach).to_contain_text("Complete your first task")
|
||||
assert page.evaluate("document.documentElement.scrollWidth <= window.innerWidth")
|
||||
assert page.evaluate("window.firstTaskOutcomeProbe.completeOutcome()") is True
|
||||
completion = page.evaluate("""() => {
|
||||
const completed = window.firstTaskOutcomeProbe.completeOutcome();
|
||||
return {
|
||||
completed,
|
||||
status: document.querySelector('#today-sync-status').textContent,
|
||||
pending: Object.keys(localStorage).filter(key =>
|
||||
key.startsWith('stackchain.today-sync.v1.timmy.operation.')),
|
||||
};
|
||||
}""")
|
||||
assert completion["completed"] is True
|
||||
assert completion["pending"]
|
||||
assert "sync pending" in completion["status"]
|
||||
expect(page.locator("#mobile-first-task-receipt")).to_be_visible()
|
||||
expect(coach).to_be_hidden()
|
||||
expect(page.locator("#today-sync-status")).to_contain_text("Today saved to account")
|
||||
remote_activation = page.evaluate("""async () => {
|
||||
const response = await fetch('api/v1/today');
|
||||
return (await response.json()).first_task_state;
|
||||
}""")
|
||||
assert remote_activation == "complete"
|
||||
assert page.evaluate("document.documentElement.scrollWidth <= window.innerWidth")
|
||||
|
||||
fresh_context = browser.new_context(
|
||||
|
||||
@@ -278,7 +278,16 @@ def test_release_artifact_plans_hands_off_and_opens_next_mobile_issue(tmp_path:
|
||||
assert page.evaluate("""() => !Object.keys(localStorage).some(
|
||||
key => key.startsWith('stackchain.today-sync.v1.timmy.operation.')
|
||||
)""")
|
||||
expect(page.locator("#today-break-status")).to_contain_text("On break · resume in")
|
||||
try:
|
||||
expect(page.locator("#today-break-status")).to_contain_text("On break · resume in")
|
||||
except AssertionError as error:
|
||||
raise AssertionError(page.evaluate("""() => ({
|
||||
login: document.querySelector('#current-user')?.textContent,
|
||||
timers: Object.fromEntries(Object.keys(localStorage)
|
||||
.filter(key => key.startsWith('stackchain.today-timer.v1.'))
|
||||
.map(key => [key, JSON.parse(localStorage.getItem(key))])),
|
||||
status: document.querySelector('#today-break-status').outerHTML,
|
||||
})""")) from error
|
||||
if page.locator("#issue-sheet").get_attribute("class") == "issue-sheet open":
|
||||
page.locator("#close-issue-sheet").click()
|
||||
if page.locator("#plan-today-sheet").is_visible():
|
||||
|
||||
@@ -117,6 +117,32 @@ const poller = createContextPoller({{
|
||||
}
|
||||
|
||||
|
||||
def test_context_poller_can_force_a_full_identity_refresh_after_adoption():
|
||||
script = f"""
|
||||
const createContextPoller = require({json.dumps(str(POLLER))});
|
||||
const requested = [];
|
||||
const seed = {{
|
||||
context:{{user:{{login:'timmy'}}}}, events:[], notifications:[],
|
||||
revisions:{{context:'0123456789abcdef.1',events:'fedcba9876543210.2'}},
|
||||
}};
|
||||
const poller = createContextPoller({{
|
||||
fetchContext: revisions => {{
|
||||
requested.push({{...revisions}});
|
||||
return Promise.resolve({{...seed, freshness:{{sections:{{context:{{degraded:false}}}}}}}});
|
||||
}},
|
||||
onSnapshot: () => {{}}, onError: error => {{ throw error; }},
|
||||
setTimer: () => 1, clearTimer: () => {{}},
|
||||
}});
|
||||
poller.adopt(seed);
|
||||
(async () => {{
|
||||
await poller.refresh({{force:true, full:true}});
|
||||
process.stdout.write(JSON.stringify({{requested}}));
|
||||
}})();
|
||||
"""
|
||||
|
||||
assert run_node(script) == {"requested": [{}]}
|
||||
|
||||
|
||||
def test_context_poller_adopts_progressive_snapshot_before_revision_conditional_refresh():
|
||||
script = f"""
|
||||
const createContextPoller = require({json.dumps(str(POLLER))});
|
||||
@@ -200,6 +226,9 @@ def test_dashboard_adopts_progressive_snapshot_or_falls_back_to_immediate_load()
|
||||
assert "let adoptedProgressiveSnapshot = contextPoller.adopt(progressiveWorkHandoff?.liveSnapshot);" in source
|
||||
assert "contextPoller.adoptPending(progressiveWorkHandoff.liveSnapshotPromise)" in source
|
||||
assert "if (!adoptedProgressiveSnapshot) await load();" in source
|
||||
assert "contextPoller.refresh({ force:true, full:true })" in source
|
||||
assert "fetchReviewJson('api/v1/background-identity')" in source
|
||||
assert "initialAccountRecovery = timerView.restore(todaySync.flush());" in source
|
||||
|
||||
|
||||
def test_context_poller_uses_failed_section_retry_before_healthy_freshness_deadline():
|
||||
|
||||
Reference in new issue
Block a user