T-571 降低更新前台抢焦点
This commit is contained in:
@@ -1002,6 +1002,9 @@ class EditorLoginTests(unittest.TestCase):
|
||||
self.assertTrue(result["blob_seen"])
|
||||
self.assertEqual(1, result["upload_state"]["busy_count"])
|
||||
self.assertIn("blob:", "\n".join(result["upload_state"]["srcs"]))
|
||||
self.assertIn("before_srcs", result)
|
||||
self.assertTrue(result["before_srcs"])
|
||||
self.assertFalse(any(str(src).startswith("blob:") for src in result["before_srcs"]))
|
||||
|
||||
def test_replace_cover_reports_page_upload_error_with_state(self):
|
||||
cdp = FakeCoverCDP(count=8, upload_mode="error")
|
||||
@@ -1054,6 +1057,105 @@ class EditorLoginTests(unittest.TestCase):
|
||||
self.assertIn("新封面上传仍在处理中", result["error"])
|
||||
click_update.assert_not_called()
|
||||
|
||||
def test_apply_task_background_drag_failure_recovers_foreground_without_replacing_again(self):
|
||||
cdp = FakeCoverCDP(count=8)
|
||||
cdp.confirm_clicked = True
|
||||
cdp.uploaded = True
|
||||
cdp.closed = False
|
||||
cdp.close = lambda: setattr(cdp, "closed", True)
|
||||
events = []
|
||||
|
||||
with mock.patch("app.editor.open_product", return_value=cdp), mock.patch(
|
||||
"app.editor.replace_cover",
|
||||
return_value={
|
||||
"ok": False,
|
||||
"reason": "DRAG_NOT_FIRST",
|
||||
"new_src": cdp.new_rect["src"],
|
||||
},
|
||||
) as replace_cover, mock.patch(
|
||||
"app.editor.click_update",
|
||||
return_value={"clicked": True, "reason": None},
|
||||
):
|
||||
result = editor.apply_task(
|
||||
{"debug_port": 9222},
|
||||
{"item_id": "51100639510", "new_cover_path": "new.jpg"},
|
||||
bring_to_front=False,
|
||||
on_step=events.append,
|
||||
)
|
||||
|
||||
self.assertTrue(result["committed"])
|
||||
replace_cover.assert_called_once()
|
||||
self.assertIn(("Page.bringToFront", {}), cdp.sent)
|
||||
self.assertTrue(cdp.dragged)
|
||||
self.assertEqual(1, len(cdp.drag_calls))
|
||||
self.assertTrue(result["cover"]["foreground_recovery"]["ok"])
|
||||
self.assertTrue(any(event.get("step") == "cover_retry_foreground" for event in events))
|
||||
|
||||
def test_apply_task_background_upload_processing_recovers_by_waiting_current_upload(self):
|
||||
cdp = FakeCoverCDP(count=8)
|
||||
cdp.confirm_clicked = True
|
||||
cdp.uploaded = True
|
||||
cdp.closed = False
|
||||
cdp.close = lambda: setattr(cdp, "closed", True)
|
||||
before_srcs = [rect["src"] for rect in cdp.after_delete]
|
||||
|
||||
with mock.patch("app.editor.open_product", return_value=cdp), mock.patch(
|
||||
"app.editor.replace_cover",
|
||||
return_value={
|
||||
"ok": False,
|
||||
"reason": "UPLOAD_STILL_PROCESSING",
|
||||
"before_srcs": before_srcs,
|
||||
"upload_state": {"busy_count": 1},
|
||||
"blob_seen": True,
|
||||
},
|
||||
) as replace_cover, mock.patch(
|
||||
"app.editor.click_update",
|
||||
return_value={"clicked": True, "reason": None},
|
||||
), mock.patch("app.editor.time.sleep"):
|
||||
result = editor.apply_task(
|
||||
{"debug_port": 9222},
|
||||
{"item_id": "51100639510", "new_cover_path": "new.jpg"},
|
||||
bring_to_front=False,
|
||||
)
|
||||
|
||||
self.assertTrue(result["committed"])
|
||||
replace_cover.assert_called_once()
|
||||
self.assertIn(("Page.bringToFront", {}), cdp.sent)
|
||||
self.assertTrue(cdp.dragged)
|
||||
self.assertTrue(result["cover"]["foreground_recovery"]["ok"])
|
||||
self.assertEqual("UPLOAD_STILL_PROCESSING", result["cover"]["original_reason"])
|
||||
|
||||
def test_apply_task_background_upload_recovery_requires_before_srcs(self):
|
||||
cdp = FakeCoverCDP(count=8)
|
||||
cdp.confirm_clicked = True
|
||||
cdp.uploaded = True
|
||||
cdp.closed = False
|
||||
cdp.close = lambda: setattr(cdp, "closed", True)
|
||||
|
||||
with mock.patch("app.editor.open_product", return_value=cdp), mock.patch(
|
||||
"app.editor.replace_cover",
|
||||
return_value={
|
||||
"ok": False,
|
||||
"reason": "UPLOAD_TIMEOUT",
|
||||
"upload_state": {"busy_count": 0},
|
||||
},
|
||||
) as replace_cover, mock.patch("app.editor.click_update") as click_update:
|
||||
result = editor.apply_task(
|
||||
{"debug_port": 9222},
|
||||
{"item_id": "51100639510", "new_cover_path": "new.jpg"},
|
||||
bring_to_front=False,
|
||||
)
|
||||
|
||||
self.assertFalse(result["committed"])
|
||||
replace_cover.assert_called_once()
|
||||
self.assertIn(("Page.bringToFront", {}), cdp.sent)
|
||||
self.assertFalse(cdp.dragged)
|
||||
self.assertEqual(
|
||||
"MISSING_BEFORE_SRCS",
|
||||
result["cover"]["foreground_recovery"]["reason"],
|
||||
)
|
||||
click_update.assert_not_called()
|
||||
|
||||
def test_replace_cover_full_slots_reports_missing_delete_button(self):
|
||||
cdp = FakeCoverCDP(count=9, delete_click=False)
|
||||
|
||||
|
||||
+64
-3
@@ -4423,12 +4423,14 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
tasks = db.list_tasks(batch_id=batch_id, path=cfg["db_path"])
|
||||
applied_aliases = []
|
||||
close_flags = []
|
||||
foreground_flags = []
|
||||
progress = []
|
||||
rows = []
|
||||
|
||||
def fake_apply(account, task, close_success_tab=False, on_step=None):
|
||||
def fake_apply(account, task, close_success_tab=False, on_step=None, bring_to_front=True):
|
||||
applied_aliases.append(account.alias)
|
||||
close_flags.append(close_success_tab)
|
||||
foreground_flags.append(bring_to_front)
|
||||
if account.alias == "alias-a":
|
||||
return {"committed": True, "error": None}
|
||||
if account.alias == "alias-b":
|
||||
@@ -4453,6 +4455,7 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
|
||||
self.assertEqual(["alias-a", "alias-b"], applied_aliases)
|
||||
self.assertEqual([True, True], close_flags)
|
||||
self.assertEqual([True, True], foreground_flags)
|
||||
self.assertFalse(summary["ok"])
|
||||
self.assertEqual(3, summary["total"])
|
||||
self.assertEqual(3, summary["done"])
|
||||
@@ -4495,6 +4498,61 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
|
||||
self.assert_removed(temp_dir)
|
||||
|
||||
def test_apply_worker_brings_each_account_to_front_only_once_across_batches(self):
|
||||
with self.make_temp_dir() as temp_dir:
|
||||
cfg = self.make_config(temp_dir)
|
||||
accounts.create_account("主店", "alias-a", debug_port=9222, config=cfg)
|
||||
batch_id = db.create_batch(["input.xlsx"], path=cfg["db_path"])
|
||||
db.insert_tasks(
|
||||
batch_id,
|
||||
[
|
||||
{
|
||||
"source_file_abs": os.path.join(temp_dir, "input.xlsx"),
|
||||
"source_sheet": "商品",
|
||||
"source_row": 2,
|
||||
"account_name": "Excel主店",
|
||||
"alias": "alias-a",
|
||||
"item_id": "51100639510",
|
||||
},
|
||||
{
|
||||
"source_file_abs": os.path.join(temp_dir, "input.xlsx"),
|
||||
"source_sheet": "商品",
|
||||
"source_row": 3,
|
||||
"account_name": "Excel主店",
|
||||
"alias": "alias-a",
|
||||
"item_id": "51100639511",
|
||||
},
|
||||
],
|
||||
path=cfg["db_path"],
|
||||
)
|
||||
for task in db.list_tasks(batch_id=batch_id, path=cfg["db_path"]):
|
||||
db.set_collected(task.id, "旧标题", "old.jpg", path=cfg["db_path"])
|
||||
db.set_generated(task.id, "新标题", "new.jpg", path=cfg["db_path"])
|
||||
tasks = db.list_tasks(batch_id=batch_id, path=cfg["db_path"])
|
||||
foreground_flags = []
|
||||
|
||||
def fake_apply(account, task, close_success_tab=False, on_step=None, bring_to_front=True):
|
||||
foreground_flags.append(bring_to_front)
|
||||
return {"committed": True, "error": None}
|
||||
|
||||
with mock.patch("app.gui.chrome.is_running", return_value=True), \
|
||||
mock.patch(
|
||||
"app.gui.accounts.detect_login",
|
||||
return_value={"logged_in": True, "reason": None},
|
||||
), mock.patch("app.gui.editor.apply_task", side_effect=fake_apply):
|
||||
summary = ApplyWorker(
|
||||
tasks,
|
||||
db_path=cfg["db_path"],
|
||||
config=cfg,
|
||||
batch_size=1,
|
||||
).execute()
|
||||
|
||||
self.assertTrue(summary["ok"])
|
||||
self.assertEqual([True, False], foreground_flags)
|
||||
self.assertEqual(2, summary["batch_count"])
|
||||
|
||||
self.assert_removed(temp_dir)
|
||||
|
||||
def test_apply_worker_dry_run_only_previews_and_logs_without_mutating_tasks(self):
|
||||
with self.make_temp_dir() as temp_dir:
|
||||
cfg = self.make_config(temp_dir)
|
||||
@@ -4596,9 +4654,11 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
tasks = db.list_tasks(batch_id=batch_id, path=cfg["db_path"])
|
||||
started = {"alias-a": threading.Event(), "alias-b": threading.Event()}
|
||||
thread_names = set()
|
||||
foreground_by_alias = {}
|
||||
|
||||
def fake_apply(account, task, close_success_tab=False, on_step=None):
|
||||
def fake_apply(account, task, close_success_tab=False, on_step=None, bring_to_front=True):
|
||||
thread_names.add(threading.current_thread().name)
|
||||
foreground_by_alias[account.alias] = bring_to_front
|
||||
started[account.alias].set()
|
||||
other = "alias-b" if account.alias == "alias-a" else "alias-a"
|
||||
self.assertTrue(started[other].wait(2))
|
||||
@@ -4621,6 +4681,7 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
self.assertTrue(summary["parallel_accounts"])
|
||||
self.assertEqual(2, summary["applied"])
|
||||
self.assertGreaterEqual(len(thread_names), 2)
|
||||
self.assertEqual({"alias-a": True, "alias-b": True}, foreground_by_alias)
|
||||
updated = db.list_tasks(batch_id=batch_id, path=cfg["db_path"])
|
||||
self.assertTrue(all(task.stage == "applied" for task in updated))
|
||||
|
||||
@@ -6461,7 +6522,7 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
task = db.list_tasks(batch_id=batch_id, path=cfg["db_path"])[0]
|
||||
diagnostic_log_dir = os.path.join(temp_dir, "logs")
|
||||
|
||||
def fake_apply(account, task, close_success_tab=False, on_step=None):
|
||||
def fake_apply(account, task, close_success_tab=False, on_step=None, bring_to_front=True):
|
||||
on_step({"step": "open_product", "result": "start"})
|
||||
on_step({"step": "replace_cover", "result": "failed", "detail": "token=SECRET"})
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user