Workday real-tenant validation (WW-32)¶
WW-32 was blocked pending a live Workday tenant. Andrew provided a real one — the CVS Health "Staff Software Development Engineer" posting, which applies through CVS's Workday. This records what a read-only inspection of that tenant confirmed. No account was created, nothing was signed into, no data was entered, nothing was submitted — the walk stopped at the account wall.
The tenant & the flow¶
- Careers site:
jobs.cvshealth.com(Phenom-hosted). "Apply Now" → ahvhapplyredirect → the Workday tenant. - Workday tenant:
cvshealth.wd1.myworkdayjobs.com, siteCVS_Health_Careers. - Job apply URL:
…/CVS_Health_Careers/job/IL---Work-from-home/Staff-Software-Development-Engineer_R0898371/apply - Apply entry page (
/apply) offers three standard Workday options, each a realdata-automation-id: autofillWithResume— "Autofill with Resume" →/apply/autofillWithResumeapplyManually— "Apply Manually" →/apply/applyManuallyuseMyLastApplication— "Use My Last Application" →/apply/useMyLastApplication- Account wall (reached via Apply Manually,
/apply/applyManually): a "Sign In" page offering Sign in with Google / LinkedIn / email. Confirmeddata-automation-ids:applyFlowPage,progressBar,signInContent,GoogleSignInButton,utilityButtonSignIn,backToJobPosting,jobTitleHeading.
What this validates in the app¶
- ATS detection —
AtsDetectorclassifiesmyworkdayjobs.comasAtsKind.Workdayand extracts the tenant host. CVS'scvshealth.wd1.myworkdayjobs.commatches. ✅ - Account-wall handling —
WorkdayAutomationEngine.SignInAsyncraises the account wall unconditionally on first visit (no vault entry → provision credential, capture the page's actual URL as the "Open site" target, park atAwaitingAccount, return false). It never types a stored password and never tries to detect the wall by page content. So the real CVS entry flow (/apply→ Apply Manually → Google/LinkedIn/email sign-in) is handled correctly by design: the engine parks and the user navigates the entry + sign-in, then resumes. No dependency on a/loginURL (the CVS wall lives at/apply/applyManually). ✅ - Selector conventions — the real tenant uses exactly the durable
data-automation-idconventionWorkdaySelectorsis built on (applyFlowPage,signInContent,progressBar,jobTitleHeading,backToJobPosting). The post-sign-in form fields (legalNameSection_firstName,formField-degree,dateSectionMonth-input,addButton,formField-skills, …) are standard Workday automation-ids and could not be live-checked without an account, but the account-wall inspection confirms this tenant follows the same convention. ✅
Signed-in "My Information" inspection (WW-32 finish)¶
Andrew signed into the tenant himself (I never handled credentials, filled a field, or submitted). That advanced the flow to step 2 "My Information", which let me read the real form fields. This surfaced a genuine selector defect the fake ScraperLab site had hidden:
- Real Workday puts the
data-automation-idon the field CONTAINER<div>(formField-legalName--firstName,formField-addressLine1,formField-postalCode,formField-phoneNumber,formField-countryRegion,formField-source, …). The inner<input>carries nodata-automation-idand noaria-label— onlyid/name(e.g.name=legalName--firstName,name=addressLine1,name=postalCode,name=phoneNumber). - Our contact selectors were all
input[data-automation-id=…]/input[aria-label=…](shape of the fake site). Against this real tenant: - First/Last/Address/City matched only via the last-resort
input[name*=…]fallback. - Postal code FAILED — real
name=postalCode, our only name fallback was*='zip'. - Phone FAILED — real
name=phoneNumber,type=text(nottel), no aria; the chain had nonamefallback at all. - Fix (committed): every contact chain now LEADS with the container-scoped
[data-automation-id='formField-…'] inputselector (the same durable pattern the app already used for the degree/skills/source dropdowns), with the old ids + newname*='phone'/name*='postal'fallbacks kept. State isformField-countryRegion— a listbox button (aria-label="State Select One Required"), consistent with the app's "State is a dropdown a text fill can't drive" note.formField-source(How did you hear, WW-38) matched as-is.
The later steps (My Experience repeater, Education, Skills) already use the container-scoped
formField-* pattern this fix aligns the contact fields to, so they weren't the defect — but
they couldn't be live-checked without completing the required My Information fields (not done).
Limitation (unchanged, by design)¶
The multi-step application form (My Information, Experience repeater, Education, Skills, Voluntary Disclosures) sits behind account creation. Validating those field selectors live requires a signed-in session — the app is built to hand that off to the user at the account wall, and the autonomous build never creates accounts or signs in. So the repeater/date/skills selectors remain proven against the ScraperLab fixtures plus Workday's documented automation-id convention (which this real tenant corroborates), not a live signed-in form.
Verdict¶
No code change needed — the design holds against a real Workday tenant. WW-32's remaining piece (live validation of the signed-in form fields) needs a session a human drives, which is exactly the account-wall handoff the engine already implements.