If Voice ID is partially set up, the login page redirects to https://client.schwab.com/service/forms/VoiceBiometric instead of whichever page was selected:

The relevant HTML fragment for clicking "Cancel", which just skips voice activation enabling and going to the correct post-login page, is
<div class="background-Highlight">
<div id="divEnroll" class="section-msg">
<div id="divCmsReadyToEnroll">
<b>You're almost done!</b> Click Activate Voice ID and use your new voice ID the next time you call Schwab.
</div>
<div id="divButtonAreaEnroll" class="space-bttonarea">
<a role="button" id="btnCancel" class="button-secondary" href="#">
<span>Cancel</span>
</a>
<a role="button" id="btnActivateVoiceId" class="button-primary" href="/Service/Forms/VoiceBiometric/VoiceBiometricActivate">
<span>Activate Voice ID</span>
</a>
</div>
</div>
</div>
(Full page html is voice_activation_page_redacted.html.zip)
It would be nice if
|
await self.page.wait_for_url(re.compile(r"app/trade"), wait_until="domcontentloaded") # Making it more robust than specifying an exact url which may change. |
would also wait for
service/forms/VoiceBiometric, and cancel if necessary.
If Voice ID is partially set up, the login page redirects to https://client.schwab.com/service/forms/VoiceBiometric instead of whichever page was selected:

The relevant HTML fragment for clicking "Cancel", which just skips voice activation enabling and going to the correct post-login page, is
(Full page html is voice_activation_page_redacted.html.zip)
It would be nice if
schwab-api/schwab_api/authentication.py
Line 167 in 4ecc624
would also wait for
service/forms/VoiceBiometric, and cancel if necessary.