@@ -4829,12 +4829,50 @@ test('CAPTCHA challenge gate blocks dismiss/resubmit mutations but allows the on
48294829 `${label}: ${toolName} escaped post-solve verification`,
48304830 );
48314831 }
4832- agent._captchaGateStates.set(88, { ...active, status: 'manual_required' });
4832+ agent._captchaGateStates.set(88, {
4833+ ...active,
4834+ status: 'manual_required',
4835+ publicGate: { ...active.publicGate, status: 'manual_required' },
4836+ });
48334837 assert.equal(
48344838 agent._captchaGateBlockResult(88, 'solve_captcha')?.manualCompletionRequired,
48354839 true,
48364840 `${label}: failed/unsupported challenge allowed another paid solve`,
48374841 );
4842+ assert.equal(agent._captchaGateBlockResult(88, 'done'), null, `${label}: manual gate blocked partial completion`);
4843+ for (const toolName of ['navigate', 'new_tab', 'go_back', 'go_forward']) {
4844+ assert.equal(agent._captchaGateBlockResult(88, toolName), null, `${label}: manual gate blocked abandonment via ${toolName}`);
4845+ }
4846+ assert.equal(
4847+ agent._captchaGateBlockResult(88, 'click_ax')?.manualCompletionRequired,
4848+ true,
4849+ `${label}: abandonment exemption allowed an in-document mutation`,
4850+ );
4851+ const sameDocumentResult = {};
4852+ assert.equal(
4853+ agent._clearCaptchaGateAfterNavigation(
4854+ 88,
4855+ 'navigate',
4856+ 'https://example.test/signup?step=1',
4857+ 'https://example.test/signup?step=2',
4858+ sameDocumentResult,
4859+ ),
4860+ null,
4861+ `${label}: query-only navigation bypassed the challenged document gate`,
4862+ );
4863+ assert.equal(agent._captchaGateStates.has(88), true, `${label}: same-document navigation deleted the gate`);
4864+ const abandonmentResult = {};
4865+ const abandoned = agent._clearCaptchaGateAfterNavigation(
4866+ 88,
4867+ 'navigate',
4868+ 'https://example.test/signup',
4869+ 'https://other.test/home',
4870+ abandonmentResult,
4871+ );
4872+ assert.equal(abandoned?.status, 'cleared', `${label}: leaving the challenged document did not clear the gate`);
4873+ assert.equal(abandoned?.clearedByNavigation, true, `${label}: navigation clearance reason missing`);
4874+ assert.equal(abandonmentResult.captchaGate?.clearedByNavigation, true, `${label}: navigation result omitted gate clearance`);
4875+ assert.equal(agent._captchaGateStates.has(88), false, `${label}: abandoned document gate remained persisted`);
48384876 }
48394877});
48404878
@@ -52700,6 +52738,16 @@ test('enabled CAPTCHA gate performs a read-only dialog preflight before the firs
5270052738 assert.equal(disabledGate?.solverDisabled, true, `${build}: disabled preflight did not explain manual routing`);
5270152739 assert.equal(disabledAgent._captchaGateStates.get(2)?.challengeFrameId, 0, `${build}: disabled preflight discarded the challenge frame identity`);
5270252740 assert.equal(disabledAgent._captchaGateBlockResult(2, 'click_ax')?.manualCompletionRequired, true, `${build}: disabled preflight allowed the challenge mutation`);
52741+
52742+ const abandonmentAgent = new AgentClass({});
52743+ abandonmentAgent.captchaSolverEnabled = false;
52744+ const abandonmentGate = await abandonmentAgent._captchaMutationPreflight(
52745+ 3,
52746+ 'navigate',
52747+ { url: 'https://other.test/home' },
52748+ );
52749+ assert.equal(abandonmentGate, null, `${build}: navigation away armed a CAPTCHA gate`);
52750+ assert.equal(abandonmentAgent._captchaGateStates.has(3), false, `${build}: navigation preflight persisted a challenge gate`);
5270352751 });
5270452752 }
5270552753});
0 commit comments