diff --git a/.build.hash b/.build.hash index 51c0d17..2d5e863 100644 --- a/.build.hash +++ b/.build.hash @@ -1 +1 @@ -24c4644c626acf48ddca3964105cd9bfa267d82a-372bcf506971f56c4911b429b9f5de5bc37ed008-e9eccd451b778829eb2f2c9752c670b707e1268b +720d57c0d6d787c629f53d47689088a50b9e9b5b-372bcf506971f56c4911b429b9f5de5bc37ed008-e9eccd451b778829eb2f2c9752c670b707e1268b diff --git a/playwright-report/index.html b/playwright-report/index.html deleted file mode 100644 index ded81cc..0000000 --- a/playwright-report/index.html +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - Playwright Test Report - - - - -
- - - \ No newline at end of file diff --git a/playwright.config.mjs b/playwright.config.mjs index 41dc5a5..0742ebd 100644 --- a/playwright.config.mjs +++ b/playwright.config.mjs @@ -1,15 +1,27 @@ - import { defineConfig } from '@playwright/test'; - +import { defineConfig, devices } from '@playwright/test'; + export default defineConfig({ // Limit Playwright to E2E specs only testDir: '/home/jcoakley/aptiva-dev1-app/tests/e2e', testMatch: /.*\.spec\.(?:mjs|js|ts)$/, - use: { - baseURL: process.env.PW_BASE_URL || 'http://localhost:3000', - trace: 'on-first-retry', - screenshot: 'only-on-failure', - video: 'retain-on-failure', - }, - retries: 1, - reporter: [['list'], ['html', { open: 'never' }]], - }); \ No newline at end of file + + use: { + baseURL: process.env.PW_BASE_URL || 'http://localhost:3000', + trace: 'on-first-retry', + screenshot: 'only-on-failure', + video: 'retain-on-failure', + }, + + retries: 0, + // Add 'blob' so Playwright persists failures for --last-failed + reporter: [['list'], ['html', { open: 'never' }], ['blob']], + + // Make Edge the default (you asked earlier) + projects: [ + { + name: 'edge', + use: { ...devices['Desktop Edge'] }, + }, + ], + }); + diff --git a/src/components/CollegeProfileForm.js b/src/components/CollegeProfileForm.js index 18da6a7..a41f801 100644 --- a/src/components/CollegeProfileForm.js +++ b/src/components/CollegeProfileForm.js @@ -2,6 +2,8 @@ import React, { useEffect, useState, useRef } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import apiFetch from '../auth/apiFetch.js'; import moment from 'moment/moment.js'; +import Modal from './ui/modal.js'; +import FinancialAidWizard from './FinancialAidWizard.js'; const authFetch = apiFetch; // keep local name, new implementation /** ----------------------------------------------------------- @@ -62,9 +64,11 @@ export default function CollegeProfileForm() { const [graduationTouched, setGraduationTouched] = useState(false); const [programLengthTouched, setProgramLengthTouched] = useState(false); const [selectedUnitId, setSelectedUnitId] = useState(null); + const [showAidWizard, setShowAidWizard] = useState(false); const schoolPrevRef = useRef(''); const programPrevRef = useRef(''); const lastSchoolText = useRef(''); + const canonicalSchoolName = useRef(''); // the exact, server-known school name for selectedUnitId const [form, setForm] = useState({ @@ -130,7 +134,10 @@ const onSchoolInput = async (e) => { selected_program: value ? prev.selected_program : '', // clear if user erased school program_type: '' })); - lastSchoolText.current = value; + setSelectedUnitId(null); + canonicalSchoolName.current = ''; + setSchoolValid(value.trim() === ''); // empty = neutral, any text = invalid until validated + lastSchoolText.current = value; } if (!value.trim()) { setSchoolSug([]); schoolPrevRef.current = ''; return; } const it = e?.nativeEvent?.inputType; // 'insertReplacementText' on datalist pick @@ -199,8 +206,10 @@ const onProgramInput = async (e) => { })(); }, [form.selected_school, form.selected_program]); - // When selected_school changes (after commit/blur), reset program suggestions/types useEffect(() => { + // Only clear when the change came from the user's typing (onSchoolInput sets lastSchoolText) + const typed = (form.selected_school || '').trim() === (lastSchoolText.current || '').trim(); + if (!typed) return; // programmatic changes (initial load, API normalization) → keep UNITID & types setProgSug([]); setTypes([]); setSelectedUnitId(null); @@ -228,7 +237,8 @@ const onProgramInput = async (e) => { const n = Number(normalized.tuition); setAutoTuition(Number.isFinite(n) ? n : 0); } - if (normalized.unit_id) setSelectedUnitId(normalized.unit_id); + if (normalized.unit_id) setSelectedUnitId(normalized.unit_id); + if (normalized.selected_school) canonicalSchoolName.current = normalized.selected_school; // If profile came with school+program, load types so Degree Type select is populated if ((normalized.selected_school || '') && (normalized.selected_program || '')) { try { @@ -245,50 +255,104 @@ const onProgramInput = async (e) => { }, [careerId, id]); - async function handleSave(){ - try{ - - // Compute chosen tuition exactly like Onboarding (manual override wins; blank => auto) + async function handleSave() { + try { + // Compute chosen tuition exactly like Onboarding (manual override wins; blank => auto) const chosenTuition = (manualTuition.trim() === '') ? autoTuition : (Number.isFinite(parseFloat(manualTuition)) ? parseFloat(manualTuition) : autoTuition); - // Confirm user actually picked from list (one alert, on Save only) - const school = (form.selected_school || '').trim().toLowerCase(); - const prog = (form.selected_program || '').trim().toLowerCase(); - // validate against current server suggestions (not local files) - const exactSchool = school && schoolSug.find(o => - (o.name || '').toLowerCase() === school - ); + const schoolText = (form.selected_school || '').trim(); + const progText = (form.selected_program || '').trim(); + const school = schoolText.toLowerCase(); + const prog = progText.toLowerCase(); - if (school && !exactSchool) { - setSchoolValid(false); - alert('Please pick a school from the list.'); - return; - } - const exactProgram = prog && progSug.find(p => - (p.program || '').toLowerCase() === prog - ); - if (prog && !exactProgram) { - setProgramValid(false); - alert('Please pick a program from the list.'); - return; - } - const body = normalisePayload({ ...form, tuition: chosenTuition, career_profile_id: careerId, unit_id: selectedUnitId ?? null }); - const res = await authFetch('/api/premium/college-profile',{ - method:'POST', - headers:{'Content-Type':'application/json'}, - body:JSON.stringify(body) - }); - if(!res.ok) throw new Error(await res.text()); - alert('Saved!'); - setForm(p => ({ ...p, tuition: chosenTuition })); - setManualTuition(String(chosenTuition)); - nav(-1); - }catch(err){ console.error(err); alert(err.message);} + // ---- SCHOOL validation ---- +const exactSchoolLocal = school && schoolSug.find(o => (o.name || '').toLowerCase() === school); +const hasCanonical = !!selectedUnitId && + canonicalSchoolName.current && + canonicalSchoolName.current.toLowerCase() === school; + +let exactSchool = exactSchoolLocal; +if (school && !exactSchool && !hasCanonical) { + // one-shot server confirm + try { + const resp = await authFetch(`/api/schools/suggest?query=${encodeURIComponent(schoolText)}&limit=50`); + const arr = resp.ok ? await resp.json() : []; + exactSchool = Array.isArray(arr) + ? arr.find(o => (o.name || '').toLowerCase() === school) + : null; + if (exactSchool && !selectedUnitId) { + setSelectedUnitId(exactSchool.unitId ?? null); + canonicalSchoolName.current = exactSchool.name || schoolText; + } + } catch {} } +if (school && !exactSchool && !hasCanonical) { + setSchoolValid(false); + alert('Please pick a school from the list.'); + return; +} + + + // ---- PROGRAM validation ---- +const progIsEmpty = progText === ''; +if (progIsEmpty) { + setProgramValid(false); + alert('Please pick a program from the list.'); + return; +} + +let exactProgram = prog && progSug.find(p => (p.program || '').toLowerCase() === prog); + +// One-shot server confirm if suggestions are empty/stale +if (!exactProgram) { + try { + const resp = await authFetch( + `/api/programs/suggest?school=${encodeURIComponent(schoolText)}&query=${encodeURIComponent(progText)}&limit=50` + ); + const arr = resp.ok ? await resp.json() : []; + exactProgram = Array.isArray(arr) + ? arr.find(p => (p.program || '').toLowerCase() === prog) + : null; + } catch {} +} + +if (!exactProgram) { + setProgramValid(false); + alert('Please pick a program from the list.'); + return; +} + + + // ---- SAVE ---- + const body = normalisePayload({ + ...form, + tuition: chosenTuition, + career_profile_id: careerId, + unit_id: selectedUnitId ?? null + }); + + const res = await authFetch('/api/premium/college-profile', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(body) + }); + if (!res.ok) throw new Error(await res.text()); + + alert('Saved!'); + setForm(p => ({ ...p, tuition: chosenTuition })); + setManualTuition(String(chosenTuition)); + nav(-1); + } catch (err) { + console.error(err); + alert(err.message); + } +} + + useEffect(() => { const sch = (form.selected_school || '').trim(); @@ -329,7 +393,9 @@ const onProgramInput = async (e) => { useEffect(() => { (async () => { const chpy = Number(form.credit_hours_per_year); - if (!selectedUnitId || + const hasCanon = canonicalSchoolName.current && + canonicalSchoolName.current.toLowerCase() === (form.selected_school || '').trim().toLowerCase(); + if (!selectedUnitId || !hasCanon || !form.program_type || !Number.isFinite(chpy) || chpy <= 0) { @@ -355,6 +421,7 @@ useEffect(() => { })(); }, [ selectedUnitId, + form.selected_school, form.program_type, form.credit_hours_per_year, form.is_in_state, @@ -482,9 +549,13 @@ return ( setForm(prev => ({ ...prev, selected_school: exact.name })); } if (!selectedUnitId) setSelectedUnitId(exact.unitId ?? null); + canonicalSchoolName.current = exact.name; + setSchoolValid(true); + return; } // Valid if empty (still choosing) OR exact chosen - setSchoolValid(trimmed === '' || !!exact); + // Empty = neutral; any other text is invalid until committed from list + setSchoolValid(trimmed === ''); }} list="school-suggestions" className={`w-full border rounded p-2 ${ @@ -513,7 +584,7 @@ return ( if (exact && form.selected_program !== exact.program) { setForm(prev => ({ ...prev, selected_program: exact.program })); } - setProgramValid(prog === '' || !!exact); + setProgramValid(prog === '' || !!exact); }} list="program-suggestions" placeholder="Start typing and choose…" @@ -639,14 +710,26 @@ return ( className="w-full border rounded p-2" /> - Annual Aid - +
+ +
+ + +
+
{/* 8 │ Existing debt */} @@ -746,15 +829,26 @@ return ( > ← Back - + + {showAidWizard && ( + setShowAidWizard(false)}> + { + setForm(prev => ({ ...prev, annual_financial_aid: estimate })); + }} + onClose={() => setShowAidWizard(false)} + /> + + )} + ); diff --git a/test-results/.last-run.json b/test-results/.last-run.json index 53f2505..8df0857 100644 --- a/test-results/.last-run.json +++ b/test-results/.last-run.json @@ -1,6 +1,21 @@ { "status": "failed", "failedTests": [ - "d94173b0fe5d7002a306-47f9b330456659f0f977" + "912b0a42e830d5eb471e-760b803445f71997ff15", + "adebddef88bcf3522d03-5564093ce53787bc37f1", + "e2a1f72bade9c08182fe-6f621548b19be1d1c340", + "04d7e1cfdd54807256b0-d6ea376eb6511af71058", + "31db8689401acd273032-cab17a91a741a429f82d", + "1c59337757c0db6c5b5a-c3a2d557647a05580ec2", + "929c2cc6ba4f564b24fc-946b201d1d2ce3bcc831", + "929c2cc6ba4f564b24fc-bb3dcb00b3273979b065", + "d94173b0fe5d7002a306-4787dc08bfe1459dba5b", + "a5366403b9bfbbbe283e-0f6aea13931c9f9dd89f", + "a5366403b9bfbbbe283e-8723b5b1a3f4093effb0", + "c167e95522508c1da576-f44184408ded1c898957", + "37ddad175c38e79b0f15-93462299db1b1756eedc", + "37ddad175c38e79b0f15-50f35c78cf5a1a8b2635", + "ed5b94c6fed68d1ded5e-79dac3b701e35033b644", + "a22878cb937d50857944-f3a10ac1ede1d0305bc5" ] } \ No newline at end of file diff --git a/test-results/04-career-explorer.core--p-126be-to-comparison-event-bridge--edge/error-context.md b/test-results/04-career-explorer.core--p-126be-to-comparison-event-bridge--edge/error-context.md new file mode 100644 index 0000000..6079791 --- /dev/null +++ b/test-results/04-career-explorer.core--p-126be-to-comparison-event-bridge--edge/error-context.md @@ -0,0 +1,253 @@ +# Page snapshot + +```yaml +- generic [ref=e3]: + - banner [ref=e4]: + - heading "AptivaAI - Career Guidance Platform" [level=1] [ref=e5] + - navigation [ref=e6]: + - button "Find Your Career" [ref=e8] [cursor=pointer] + - button "Preparing & UpSkilling for Your Career" [ref=e10] [cursor=pointer] + - button "Enhancing Your Career(Premium)" [ref=e12] [cursor=pointer]: + - text: Enhancing Your Career + - generic [ref=e13] [cursor=pointer]: (Premium) + - button "Retirement Planning (beta)(Premium)" [ref=e15] [cursor=pointer]: + - text: Retirement Planning (beta) + - generic [ref=e16] [cursor=pointer]: (Premium) + - button "Profile" [ref=e18] [cursor=pointer] + - generic [ref=e19]: + - button "Upgrade to Premium" [ref=e20] [cursor=pointer] + - button "Support" [ref=e21] [cursor=pointer] + - button "Logout" [ref=e22] [cursor=pointer] + - main [ref=e23]: + - generic [ref=e24]: + - generic [ref=e25]: + - heading "Explore Careers - use these tools to find your best fit" [level=2] [ref=e26] + - generic [ref=e27]: + - generic [ref=e28]: + - text: Search for Career + - generic [ref=e29]: "*" + - combobox "Start typing a career..." [ref=e31] + - paragraph [ref=e32]: Please pick from the dropdown when performing search. Our database is very comprehensive but can’t accommodate every job title—choose the closest match to what you’re searching for. + - generic [ref=e33]: + - heading "Career Comparison" [level=2] [ref=e34] + - button "Edit priorities" [ref=e35] [cursor=pointer] + - paragraph [ref=e36]: No careers added to comparison. + - generic [ref=e37]: + - combobox [ref=e38]: + - option "All Preparation Levels" [selected] + - option "Little or No Preparation" + - option "Some Preparation Needed" + - option "Medium Preparation Needed" + - option "Considerable Preparation Needed" + - option "Extensive Preparation Needed" + - combobox [ref=e39]: + - option "All Fit Levels" [selected] + - option "Best - Very Strong Match" + - option "Great - Strong Match" + - option "Good - Less Strong Match" + - button "Reload Career Suggestions" [active] [ref=e40] [cursor=pointer] + - generic [ref=e41]: + - generic [ref=e42]: ⚠️ + - generic [ref=e43]: = May have limited data for this career path + - generic [ref=e44]: + - button "Amusement & Recreation Attendants ⚠️" [ref=e45] [cursor=pointer]: + - generic [ref=e46] [cursor=pointer]: Amusement & Recreation Attendants + - generic [ref=e47] [cursor=pointer]: ⚠️ + - button "Baristas ⚠️" [ref=e48] [cursor=pointer]: + - generic [ref=e49] [cursor=pointer]: Baristas + - generic [ref=e50] [cursor=pointer]: ⚠️ + - button "Bus Drivers, School" [ref=e51] [cursor=pointer]: + - generic [ref=e52] [cursor=pointer]: Bus Drivers, School + - button "Childcare Workers" [ref=e53] [cursor=pointer]: + - generic [ref=e54] [cursor=pointer]: Childcare Workers + - button "Coaches & Scouts" [ref=e55] [cursor=pointer]: + - generic [ref=e56] [cursor=pointer]: Coaches & Scouts + - button "Concierges" [ref=e57] [cursor=pointer]: + - generic [ref=e58] [cursor=pointer]: Concierges + - button "Exercise Trainers & Group Fitness Instructors" [ref=e59] [cursor=pointer]: + - generic [ref=e60] [cursor=pointer]: Exercise Trainers & Group Fitness Instructors + - button "Food Servers, Nonrestaurant ⚠️" [ref=e61] [cursor=pointer]: + - generic [ref=e62] [cursor=pointer]: Food Servers, Nonrestaurant + - generic [ref=e63] [cursor=pointer]: ⚠️ + - button "Funeral Attendants ⚠️" [ref=e64] [cursor=pointer]: + - generic [ref=e65] [cursor=pointer]: Funeral Attendants + - generic [ref=e66] [cursor=pointer]: ⚠️ + - button "Home Health Aides ⚠️" [ref=e67] [cursor=pointer]: + - generic [ref=e68] [cursor=pointer]: Home Health Aides + - generic [ref=e69] [cursor=pointer]: ⚠️ + - button "Hosts & Hostesses, Restaurant, Lounge, & Coffee Shop ⚠️" [ref=e70] [cursor=pointer]: + - generic [ref=e71] [cursor=pointer]: Hosts & Hostesses, Restaurant, Lounge, & Coffee Shop + - generic [ref=e72] [cursor=pointer]: ⚠️ + - button "Locker Room, Coatroom, & Dressing Room Attendants ⚠️" [ref=e73] [cursor=pointer]: + - generic [ref=e74] [cursor=pointer]: Locker Room, Coatroom, & Dressing Room Attendants + - generic [ref=e75] [cursor=pointer]: ⚠️ + - button "Nannies" [ref=e76] [cursor=pointer]: + - generic [ref=e77] [cursor=pointer]: Nannies + - button "Nursing Assistants" [ref=e78] [cursor=pointer]: + - generic [ref=e79] [cursor=pointer]: Nursing Assistants + - button "Occupational Therapy Aides" [ref=e80] [cursor=pointer]: + - generic [ref=e81] [cursor=pointer]: Occupational Therapy Aides + - button "Passenger Attendants ⚠️" [ref=e82] [cursor=pointer]: + - generic [ref=e83] [cursor=pointer]: Passenger Attendants + - generic [ref=e84] [cursor=pointer]: ⚠️ + - button "Personal Care Aides ⚠️" [ref=e85] [cursor=pointer]: + - generic [ref=e86] [cursor=pointer]: Personal Care Aides + - generic [ref=e87] [cursor=pointer]: ⚠️ + - button "Physical Therapist Aides" [ref=e88] [cursor=pointer]: + - generic [ref=e89] [cursor=pointer]: Physical Therapist Aides + - button "Recreation Workers" [ref=e90] [cursor=pointer]: + - generic [ref=e91] [cursor=pointer]: Recreation Workers + - button "Residential Advisors" [ref=e92] [cursor=pointer]: + - generic [ref=e93] [cursor=pointer]: Residential Advisors + - button "School Bus Monitors ⚠️" [ref=e94] [cursor=pointer]: + - generic [ref=e95] [cursor=pointer]: School Bus Monitors + - generic [ref=e96] [cursor=pointer]: ⚠️ + - button "Substitute Teachers, Short-Term ⚠️" [ref=e97] [cursor=pointer]: + - generic [ref=e98] [cursor=pointer]: Substitute Teachers, Short-Term + - generic [ref=e99] [cursor=pointer]: ⚠️ + - button "Teaching Assistants, Preschool, Elementary, Middle, & Secondary School ⚠️" [ref=e100] [cursor=pointer]: + - generic [ref=e101] [cursor=pointer]: Teaching Assistants, Preschool, Elementary, Middle, & Secondary School + - generic [ref=e102] [cursor=pointer]: ⚠️ + - button "Teaching Assistants, Special Education ⚠️" [ref=e103] [cursor=pointer]: + - generic [ref=e104] [cursor=pointer]: Teaching Assistants, Special Education + - generic [ref=e105] [cursor=pointer]: ⚠️ + - button "Tour Guides & Escorts ⚠️" [ref=e106] [cursor=pointer]: + - generic [ref=e107] [cursor=pointer]: Tour Guides & Escorts + - generic [ref=e108] [cursor=pointer]: ⚠️ + - button "Ushers, Lobby Attendants, & Ticket Takers ⚠️" [ref=e109] [cursor=pointer]: + - generic [ref=e110] [cursor=pointer]: Ushers, Lobby Attendants, & Ticket Takers + - generic [ref=e111] [cursor=pointer]: ⚠️ + - button "Waiters & Waitresses ⚠️" [ref=e112] [cursor=pointer]: + - generic [ref=e113] [cursor=pointer]: Waiters & Waitresses + - generic [ref=e114] [cursor=pointer]: ⚠️ + - button "Adapted Physical Education Specialists" [ref=e115] [cursor=pointer]: + - generic [ref=e116] [cursor=pointer]: Adapted Physical Education Specialists + - button "Adult Basic Education, Adult Secondary Education, & English as a Second Language Instructors" [ref=e117] [cursor=pointer]: + - generic [ref=e118] [cursor=pointer]: Adult Basic Education, Adult Secondary Education, & English as a Second Language Instructors + - button "Athletes & Sports Competitors" [ref=e119] [cursor=pointer]: + - generic [ref=e120] [cursor=pointer]: Athletes & Sports Competitors + - button "Baggage Porters & Bellhops ⚠️" [ref=e121] [cursor=pointer]: + - generic [ref=e122] [cursor=pointer]: Baggage Porters & Bellhops + - generic [ref=e123] [cursor=pointer]: ⚠️ + - button "Barbers" [ref=e124] [cursor=pointer]: + - generic [ref=e125] [cursor=pointer]: Barbers + - button "Bartenders" [ref=e126] [cursor=pointer]: + - generic [ref=e127] [cursor=pointer]: Bartenders + - button "Bus Drivers, Transit & Intercity" [ref=e128] [cursor=pointer]: + - generic [ref=e129] [cursor=pointer]: Bus Drivers, Transit & Intercity + - button "Career/Technical Education Teachers, Middle School" [ref=e130] [cursor=pointer]: + - generic [ref=e131] [cursor=pointer]: Career/Technical Education Teachers, Middle School + - button "Career/Technical Education Teachers, Secondary School" [ref=e132] [cursor=pointer]: + - generic [ref=e133] [cursor=pointer]: Career/Technical Education Teachers, Secondary School + - button "Clergy" [ref=e134] [cursor=pointer]: + - generic [ref=e135] [cursor=pointer]: Clergy + - button "Cooks, Private Household" [ref=e136] [cursor=pointer]: + - generic [ref=e137] [cursor=pointer]: Cooks, Private Household + - button "Correctional Officers & Jailers" [ref=e138] [cursor=pointer]: + - generic [ref=e139] [cursor=pointer]: Correctional Officers & Jailers + - button "Dietetic Technicians" [ref=e140] [cursor=pointer]: + - generic [ref=e141] [cursor=pointer]: Dietetic Technicians + - button "Dining Room & Cafeteria Attendants & Bartender Helpers ⚠️" [ref=e142] [cursor=pointer]: + - generic [ref=e143] [cursor=pointer]: Dining Room & Cafeteria Attendants & Bartender Helpers + - generic [ref=e144] [cursor=pointer]: ⚠️ + - button "Elementary School Teachers" [ref=e145] [cursor=pointer]: + - generic [ref=e146] [cursor=pointer]: Elementary School Teachers + - button "Fast Food & Counter Workers ⚠️" [ref=e147] [cursor=pointer]: + - generic [ref=e148] [cursor=pointer]: Fast Food & Counter Workers + - generic [ref=e149] [cursor=pointer]: ⚠️ + - button "Fitness & Wellness Coordinators" [ref=e150] [cursor=pointer]: + - generic [ref=e151] [cursor=pointer]: Fitness & Wellness Coordinators + - button "Flight Attendants" [ref=e152] [cursor=pointer]: + - generic [ref=e153] [cursor=pointer]: Flight Attendants + - button "Hairdressers, Hairstylists, & Cosmetologists" [ref=e154] [cursor=pointer]: + - generic [ref=e155] [cursor=pointer]: Hairdressers, Hairstylists, & Cosmetologists + - button "Hotel, Motel, & Resort Desk Clerks ⚠️" [ref=e156] [cursor=pointer]: + - generic [ref=e157] [cursor=pointer]: Hotel, Motel, & Resort Desk Clerks + - generic [ref=e158] [cursor=pointer]: ⚠️ + - button "Kindergarten Teachers" [ref=e159] [cursor=pointer]: + - generic [ref=e160] [cursor=pointer]: Kindergarten Teachers + - button "Licensed Practical & Licensed Vocational Nurses" [ref=e161] [cursor=pointer]: + - generic [ref=e162] [cursor=pointer]: Licensed Practical & Licensed Vocational Nurses + - button "Middle School Teachers" [ref=e163] [cursor=pointer]: + - generic [ref=e164] [cursor=pointer]: Middle School Teachers + - button "Midwives" [ref=e165] [cursor=pointer]: + - generic [ref=e166] [cursor=pointer]: Midwives + - button "Morticians, Undertakers, & Funeral Arrangers" [ref=e167] [cursor=pointer]: + - generic [ref=e168] [cursor=pointer]: Morticians, Undertakers, & Funeral Arrangers + - button "Occupational Therapy Assistants" [ref=e169] [cursor=pointer]: + - generic [ref=e170] [cursor=pointer]: Occupational Therapy Assistants + - button "Orderlies ⚠️" [ref=e171] [cursor=pointer]: + - generic [ref=e172] [cursor=pointer]: Orderlies + - generic [ref=e173] [cursor=pointer]: ⚠️ + - button "Physical Therapist Assistants" [ref=e174] [cursor=pointer]: + - generic [ref=e175] [cursor=pointer]: Physical Therapist Assistants + - button "Preschool Teachers" [ref=e176] [cursor=pointer]: + - generic [ref=e177] [cursor=pointer]: Preschool Teachers + - button "Psychiatric Aides" [ref=e178] [cursor=pointer]: + - generic [ref=e179] [cursor=pointer]: Psychiatric Aides + - button "Reservation & Transportation Ticket Agents & Travel Clerks ⚠️" [ref=e180] [cursor=pointer]: + - generic [ref=e181] [cursor=pointer]: Reservation & Transportation Ticket Agents & Travel Clerks + - generic [ref=e182] [cursor=pointer]: ⚠️ + - button "Secondary School Teachers" [ref=e183] [cursor=pointer]: + - generic [ref=e184] [cursor=pointer]: Secondary School Teachers + - button "Self-Enrichment Teachers" [ref=e185] [cursor=pointer]: + - generic [ref=e186] [cursor=pointer]: Self-Enrichment Teachers + - button "Shampooers" [ref=e187] [cursor=pointer]: + - generic [ref=e188] [cursor=pointer]: Shampooers + - button "Skincare Specialists" [ref=e189] [cursor=pointer]: + - generic [ref=e190] [cursor=pointer]: Skincare Specialists + - button "Social & Human Service Assistants" [ref=e191] [cursor=pointer]: + - generic [ref=e192] [cursor=pointer]: Social & Human Service Assistants + - button "Teaching Assistants, Postsecondary" [ref=e193] [cursor=pointer]: + - generic [ref=e194] [cursor=pointer]: Teaching Assistants, Postsecondary + - button "Telephone Operators ⚠️" [ref=e195] [cursor=pointer]: + - generic [ref=e196] [cursor=pointer]: Telephone Operators + - generic [ref=e197] [cursor=pointer]: ⚠️ + - button "Travel Guides ⚠️" [ref=e198] [cursor=pointer]: + - generic [ref=e199] [cursor=pointer]: Travel Guides + - generic [ref=e200] [cursor=pointer]: ⚠️ + - button "Cooks, Fast Food ⚠️" [ref=e201] [cursor=pointer]: + - generic [ref=e202] [cursor=pointer]: Cooks, Fast Food + - generic [ref=e203] [cursor=pointer]: ⚠️ + - button "Dishwashers ⚠️" [ref=e204] [cursor=pointer]: + - generic [ref=e205] [cursor=pointer]: Dishwashers + - generic [ref=e206] [cursor=pointer]: ⚠️ + - button "Door-to-Door Sales Workers, News & Street Vendors, & Related Workers ⚠️" [ref=e207] [cursor=pointer]: + - generic [ref=e208] [cursor=pointer]: Door-to-Door Sales Workers, News & Street Vendors, & Related Workers + - generic [ref=e209] [cursor=pointer]: ⚠️ + - button "Educational, Guidance, & Career Counselors & Advisors" [ref=e210] [cursor=pointer]: + - generic [ref=e211] [cursor=pointer]: Educational, Guidance, & Career Counselors & Advisors + - button "Helpers--Painters, Paperhangers, Plasterers, & Stucco Masons ⚠️" [ref=e212] [cursor=pointer]: + - generic [ref=e213] [cursor=pointer]: Helpers--Painters, Paperhangers, Plasterers, & Stucco Masons + - generic [ref=e214] [cursor=pointer]: ⚠️ + - button "Hospitalists" [ref=e215] [cursor=pointer]: + - generic [ref=e216] [cursor=pointer]: Hospitalists + - button "Low Vision Therapists, Orientation & Mobility Specialists, & Vision Rehabilitation Therapists" [ref=e217] [cursor=pointer]: + - generic [ref=e218] [cursor=pointer]: Low Vision Therapists, Orientation & Mobility Specialists, & Vision Rehabilitation Therapists + - button "Maids & Housekeeping Cleaners ⚠️" [ref=e219] [cursor=pointer]: + - generic [ref=e220] [cursor=pointer]: Maids & Housekeeping Cleaners + - generic [ref=e221] [cursor=pointer]: ⚠️ + - button "Nurse Midwives" [ref=e222] [cursor=pointer]: + - generic [ref=e223] [cursor=pointer]: Nurse Midwives + - button "Special Education Teachers, Preschool" [ref=e224] [cursor=pointer]: + - generic [ref=e225] [cursor=pointer]: Special Education Teachers, Preschool + - button "Substance Abuse & Behavioral Disorder Counselors ⚠️" [ref=e226] [cursor=pointer]: + - generic [ref=e227] [cursor=pointer]: Substance Abuse & Behavioral Disorder Counselors + - generic [ref=e228] [cursor=pointer]: ⚠️ + - generic [ref=e229]: + - text: This page includes information from + - link "O*NET OnLine" [ref=e230] [cursor=pointer]: + - /url: https://www.onetcenter.org + - text: by the U.S. Department of Labor, Employment & Training Administration (USDOL/ETA). Used under the + - link "CC BY 4.0 license" [ref=e231] [cursor=pointer]: + - /url: https://creativecommons.org/licenses/by/4.0/ + - text: . **O*NET®** is a trademark of USDOL/ETA. Salary and employment data are enriched with resources from the + - link "Bureau of Labor Statistics" [ref=e232] [cursor=pointer]: + - /url: https://www.bls.gov + - text: and program information from the + - link "National Center for Education Statistics" [ref=e233] [cursor=pointer]: + - /url: https://nces.ed.gov + - text: . + - button "Open chat" [ref=e234] [cursor=pointer]: + - img [ref=e235] [cursor=pointer] +``` \ No newline at end of file diff --git a/test-results/04-career-explorer.core--p-126be-to-comparison-event-bridge--edge/test-failed-1.png b/test-results/04-career-explorer.core--p-126be-to-comparison-event-bridge--edge/test-failed-1.png new file mode 100644 index 0000000..766cf40 Binary files /dev/null and b/test-results/04-career-explorer.core--p-126be-to-comparison-event-bridge--edge/test-failed-1.png differ diff --git a/test-results/04-career-explorer.core--p-126be-to-comparison-event-bridge--edge/video.webm b/test-results/04-career-explorer.core--p-126be-to-comparison-event-bridge--edge/video.webm new file mode 100644 index 0000000..48d5601 Binary files /dev/null and b/test-results/04-career-explorer.core--p-126be-to-comparison-event-bridge--edge/video.webm differ diff --git a/test-results/09-comparison-duplicate-re-10630-uplicate-remove-and-persist-edge/error-context.md b/test-results/09-comparison-duplicate-re-10630-uplicate-remove-and-persist-edge/error-context.md new file mode 100644 index 0000000..a67c01b --- /dev/null +++ b/test-results/09-comparison-duplicate-re-10630-uplicate-remove-and-persist-edge/error-context.md @@ -0,0 +1,253 @@ +# Page snapshot + +```yaml +- generic [ref=e3]: + - banner [ref=e4]: + - heading "AptivaAI - Career Guidance Platform" [level=1] [ref=e5] + - navigation [ref=e6]: + - button "Find Your Career" [ref=e8] [cursor=pointer] + - button "Preparing & UpSkilling for Your Career" [ref=e10] [cursor=pointer] + - button "Enhancing Your Career(Premium)" [ref=e12] [cursor=pointer]: + - text: Enhancing Your Career + - generic [ref=e13] [cursor=pointer]: (Premium) + - button "Retirement Planning (beta)(Premium)" [ref=e15] [cursor=pointer]: + - text: Retirement Planning (beta) + - generic [ref=e16] [cursor=pointer]: (Premium) + - button "Profile" [ref=e18] [cursor=pointer] + - generic [ref=e19]: + - button "Upgrade to Premium" [ref=e20] [cursor=pointer] + - button "Support" [ref=e21] [cursor=pointer] + - button "Logout" [ref=e22] [cursor=pointer] + - main [ref=e23]: + - generic [ref=e24]: + - generic [ref=e25]: + - heading "Explore Careers - use these tools to find your best fit" [level=2] [ref=e26] + - generic [ref=e27]: + - generic [ref=e28]: + - text: Search for Career + - generic [ref=e29]: "*" + - combobox "Start typing a career..." [ref=e31] + - paragraph [ref=e32]: Please pick from the dropdown when performing search. Our database is very comprehensive but can’t accommodate every job title—choose the closest match to what you’re searching for. + - generic [ref=e33]: + - heading "Career Comparison" [level=2] [ref=e34] + - button "Edit priorities" [ref=e35] [cursor=pointer] + - paragraph [ref=e36]: No careers added to comparison. + - generic [ref=e37]: + - combobox [ref=e38]: + - option "All Preparation Levels" [selected] + - option "Little or No Preparation" + - option "Some Preparation Needed" + - option "Medium Preparation Needed" + - option "Considerable Preparation Needed" + - option "Extensive Preparation Needed" + - combobox [ref=e39]: + - option "All Fit Levels" [selected] + - option "Best - Very Strong Match" + - option "Great - Strong Match" + - option "Good - Less Strong Match" + - button "Reload Career Suggestions" [ref=e40] [cursor=pointer] + - generic [ref=e41]: + - generic [ref=e42]: ⚠️ + - generic [ref=e43]: = May have limited data for this career path + - generic [ref=e44]: + - button "Amusement & Recreation Attendants ⚠️" [ref=e45] [cursor=pointer]: + - generic [ref=e46] [cursor=pointer]: Amusement & Recreation Attendants + - generic [ref=e47] [cursor=pointer]: ⚠️ + - button "Baristas ⚠️" [ref=e48] [cursor=pointer]: + - generic [ref=e49] [cursor=pointer]: Baristas + - generic [ref=e50] [cursor=pointer]: ⚠️ + - button "Bus Drivers, School" [ref=e51] [cursor=pointer]: + - generic [ref=e52] [cursor=pointer]: Bus Drivers, School + - button "Childcare Workers" [ref=e53] [cursor=pointer]: + - generic [ref=e54] [cursor=pointer]: Childcare Workers + - button "Coaches & Scouts" [ref=e55] [cursor=pointer]: + - generic [ref=e56] [cursor=pointer]: Coaches & Scouts + - button "Concierges" [ref=e57] [cursor=pointer]: + - generic [ref=e58] [cursor=pointer]: Concierges + - button "Exercise Trainers & Group Fitness Instructors" [ref=e59] [cursor=pointer]: + - generic [ref=e60] [cursor=pointer]: Exercise Trainers & Group Fitness Instructors + - button "Food Servers, Nonrestaurant ⚠️" [ref=e61] [cursor=pointer]: + - generic [ref=e62] [cursor=pointer]: Food Servers, Nonrestaurant + - generic [ref=e63] [cursor=pointer]: ⚠️ + - button "Funeral Attendants ⚠️" [ref=e64] [cursor=pointer]: + - generic [ref=e65] [cursor=pointer]: Funeral Attendants + - generic [ref=e66] [cursor=pointer]: ⚠️ + - button "Home Health Aides ⚠️" [ref=e67] [cursor=pointer]: + - generic [ref=e68] [cursor=pointer]: Home Health Aides + - generic [ref=e69] [cursor=pointer]: ⚠️ + - button "Hosts & Hostesses, Restaurant, Lounge, & Coffee Shop ⚠️" [ref=e70] [cursor=pointer]: + - generic [ref=e71] [cursor=pointer]: Hosts & Hostesses, Restaurant, Lounge, & Coffee Shop + - generic [ref=e72] [cursor=pointer]: ⚠️ + - button "Locker Room, Coatroom, & Dressing Room Attendants ⚠️" [ref=e73] [cursor=pointer]: + - generic [ref=e74] [cursor=pointer]: Locker Room, Coatroom, & Dressing Room Attendants + - generic [ref=e75] [cursor=pointer]: ⚠️ + - button "Nannies" [ref=e76] [cursor=pointer]: + - generic [ref=e77] [cursor=pointer]: Nannies + - button "Nursing Assistants" [ref=e78] [cursor=pointer]: + - generic [ref=e79] [cursor=pointer]: Nursing Assistants + - button "Occupational Therapy Aides" [ref=e80] [cursor=pointer]: + - generic [ref=e81] [cursor=pointer]: Occupational Therapy Aides + - button "Passenger Attendants ⚠️" [ref=e82] [cursor=pointer]: + - generic [ref=e83] [cursor=pointer]: Passenger Attendants + - generic [ref=e84] [cursor=pointer]: ⚠️ + - button "Personal Care Aides ⚠️" [ref=e85] [cursor=pointer]: + - generic [ref=e86] [cursor=pointer]: Personal Care Aides + - generic [ref=e87] [cursor=pointer]: ⚠️ + - button "Physical Therapist Aides" [ref=e88] [cursor=pointer]: + - generic [ref=e89] [cursor=pointer]: Physical Therapist Aides + - button "Recreation Workers" [ref=e90] [cursor=pointer]: + - generic [ref=e91] [cursor=pointer]: Recreation Workers + - button "Residential Advisors" [ref=e92] [cursor=pointer]: + - generic [ref=e93] [cursor=pointer]: Residential Advisors + - button "School Bus Monitors ⚠️" [ref=e94] [cursor=pointer]: + - generic [ref=e95] [cursor=pointer]: School Bus Monitors + - generic [ref=e96] [cursor=pointer]: ⚠️ + - button "Substitute Teachers, Short-Term ⚠️" [ref=e97] [cursor=pointer]: + - generic [ref=e98] [cursor=pointer]: Substitute Teachers, Short-Term + - generic [ref=e99] [cursor=pointer]: ⚠️ + - button "Teaching Assistants, Preschool, Elementary, Middle, & Secondary School ⚠️" [ref=e100] [cursor=pointer]: + - generic [ref=e101] [cursor=pointer]: Teaching Assistants, Preschool, Elementary, Middle, & Secondary School + - generic [ref=e102] [cursor=pointer]: ⚠️ + - button "Teaching Assistants, Special Education ⚠️" [ref=e103] [cursor=pointer]: + - generic [ref=e104] [cursor=pointer]: Teaching Assistants, Special Education + - generic [ref=e105] [cursor=pointer]: ⚠️ + - button "Tour Guides & Escorts ⚠️" [ref=e106] [cursor=pointer]: + - generic [ref=e107] [cursor=pointer]: Tour Guides & Escorts + - generic [ref=e108] [cursor=pointer]: ⚠️ + - button "Ushers, Lobby Attendants, & Ticket Takers ⚠️" [ref=e109] [cursor=pointer]: + - generic [ref=e110] [cursor=pointer]: Ushers, Lobby Attendants, & Ticket Takers + - generic [ref=e111] [cursor=pointer]: ⚠️ + - button "Waiters & Waitresses ⚠️" [ref=e112] [cursor=pointer]: + - generic [ref=e113] [cursor=pointer]: Waiters & Waitresses + - generic [ref=e114] [cursor=pointer]: ⚠️ + - button "Adapted Physical Education Specialists" [ref=e115] [cursor=pointer]: + - generic [ref=e116] [cursor=pointer]: Adapted Physical Education Specialists + - button "Adult Basic Education, Adult Secondary Education, & English as a Second Language Instructors" [ref=e117] [cursor=pointer]: + - generic [ref=e118] [cursor=pointer]: Adult Basic Education, Adult Secondary Education, & English as a Second Language Instructors + - button "Athletes & Sports Competitors" [ref=e119] [cursor=pointer]: + - generic [ref=e120] [cursor=pointer]: Athletes & Sports Competitors + - button "Baggage Porters & Bellhops ⚠️" [ref=e121] [cursor=pointer]: + - generic [ref=e122] [cursor=pointer]: Baggage Porters & Bellhops + - generic [ref=e123] [cursor=pointer]: ⚠️ + - button "Barbers" [ref=e124] [cursor=pointer]: + - generic [ref=e125] [cursor=pointer]: Barbers + - button "Bartenders" [ref=e126] [cursor=pointer]: + - generic [ref=e127] [cursor=pointer]: Bartenders + - button "Bus Drivers, Transit & Intercity" [ref=e128] [cursor=pointer]: + - generic [ref=e129] [cursor=pointer]: Bus Drivers, Transit & Intercity + - button "Career/Technical Education Teachers, Middle School" [ref=e130] [cursor=pointer]: + - generic [ref=e131] [cursor=pointer]: Career/Technical Education Teachers, Middle School + - button "Career/Technical Education Teachers, Secondary School" [ref=e132] [cursor=pointer]: + - generic [ref=e133] [cursor=pointer]: Career/Technical Education Teachers, Secondary School + - button "Clergy" [ref=e134] [cursor=pointer]: + - generic [ref=e135] [cursor=pointer]: Clergy + - button "Cooks, Private Household" [ref=e136] [cursor=pointer]: + - generic [ref=e137] [cursor=pointer]: Cooks, Private Household + - button "Correctional Officers & Jailers" [ref=e138] [cursor=pointer]: + - generic [ref=e139] [cursor=pointer]: Correctional Officers & Jailers + - button "Dietetic Technicians" [ref=e140] [cursor=pointer]: + - generic [ref=e141] [cursor=pointer]: Dietetic Technicians + - button "Dining Room & Cafeteria Attendants & Bartender Helpers ⚠️" [ref=e142] [cursor=pointer]: + - generic [ref=e143] [cursor=pointer]: Dining Room & Cafeteria Attendants & Bartender Helpers + - generic [ref=e144] [cursor=pointer]: ⚠️ + - button "Elementary School Teachers" [ref=e145] [cursor=pointer]: + - generic [ref=e146] [cursor=pointer]: Elementary School Teachers + - button "Fast Food & Counter Workers ⚠️" [ref=e147] [cursor=pointer]: + - generic [ref=e148] [cursor=pointer]: Fast Food & Counter Workers + - generic [ref=e149] [cursor=pointer]: ⚠️ + - button "Fitness & Wellness Coordinators" [ref=e150] [cursor=pointer]: + - generic [ref=e151] [cursor=pointer]: Fitness & Wellness Coordinators + - button "Flight Attendants" [ref=e152] [cursor=pointer]: + - generic [ref=e153] [cursor=pointer]: Flight Attendants + - button "Hairdressers, Hairstylists, & Cosmetologists" [ref=e154] [cursor=pointer]: + - generic [ref=e155] [cursor=pointer]: Hairdressers, Hairstylists, & Cosmetologists + - button "Hotel, Motel, & Resort Desk Clerks ⚠️" [ref=e156] [cursor=pointer]: + - generic [ref=e157] [cursor=pointer]: Hotel, Motel, & Resort Desk Clerks + - generic [ref=e158] [cursor=pointer]: ⚠️ + - button "Kindergarten Teachers" [ref=e159] [cursor=pointer]: + - generic [ref=e160] [cursor=pointer]: Kindergarten Teachers + - button "Licensed Practical & Licensed Vocational Nurses" [ref=e161] [cursor=pointer]: + - generic [ref=e162] [cursor=pointer]: Licensed Practical & Licensed Vocational Nurses + - button "Middle School Teachers" [ref=e163] [cursor=pointer]: + - generic [ref=e164] [cursor=pointer]: Middle School Teachers + - button "Midwives" [ref=e165] [cursor=pointer]: + - generic [ref=e166] [cursor=pointer]: Midwives + - button "Morticians, Undertakers, & Funeral Arrangers" [ref=e167] [cursor=pointer]: + - generic [ref=e168] [cursor=pointer]: Morticians, Undertakers, & Funeral Arrangers + - button "Occupational Therapy Assistants" [ref=e169] [cursor=pointer]: + - generic [ref=e170] [cursor=pointer]: Occupational Therapy Assistants + - button "Orderlies ⚠️" [ref=e171] [cursor=pointer]: + - generic [ref=e172] [cursor=pointer]: Orderlies + - generic [ref=e173] [cursor=pointer]: ⚠️ + - button "Physical Therapist Assistants" [ref=e174] [cursor=pointer]: + - generic [ref=e175] [cursor=pointer]: Physical Therapist Assistants + - button "Preschool Teachers" [ref=e176] [cursor=pointer]: + - generic [ref=e177] [cursor=pointer]: Preschool Teachers + - button "Psychiatric Aides" [ref=e178] [cursor=pointer]: + - generic [ref=e179] [cursor=pointer]: Psychiatric Aides + - button "Reservation & Transportation Ticket Agents & Travel Clerks ⚠️" [ref=e180] [cursor=pointer]: + - generic [ref=e181] [cursor=pointer]: Reservation & Transportation Ticket Agents & Travel Clerks + - generic [ref=e182] [cursor=pointer]: ⚠️ + - button "Secondary School Teachers" [ref=e183] [cursor=pointer]: + - generic [ref=e184] [cursor=pointer]: Secondary School Teachers + - button "Self-Enrichment Teachers" [ref=e185] [cursor=pointer]: + - generic [ref=e186] [cursor=pointer]: Self-Enrichment Teachers + - button "Shampooers" [ref=e187] [cursor=pointer]: + - generic [ref=e188] [cursor=pointer]: Shampooers + - button "Skincare Specialists" [ref=e189] [cursor=pointer]: + - generic [ref=e190] [cursor=pointer]: Skincare Specialists + - button "Social & Human Service Assistants" [ref=e191] [cursor=pointer]: + - generic [ref=e192] [cursor=pointer]: Social & Human Service Assistants + - button "Teaching Assistants, Postsecondary" [ref=e193] [cursor=pointer]: + - generic [ref=e194] [cursor=pointer]: Teaching Assistants, Postsecondary + - button "Telephone Operators ⚠️" [ref=e195] [cursor=pointer]: + - generic [ref=e196] [cursor=pointer]: Telephone Operators + - generic [ref=e197] [cursor=pointer]: ⚠️ + - button "Travel Guides ⚠️" [ref=e198] [cursor=pointer]: + - generic [ref=e199] [cursor=pointer]: Travel Guides + - generic [ref=e200] [cursor=pointer]: ⚠️ + - button "Cooks, Fast Food ⚠️" [ref=e201] [cursor=pointer]: + - generic [ref=e202] [cursor=pointer]: Cooks, Fast Food + - generic [ref=e203] [cursor=pointer]: ⚠️ + - button "Dishwashers ⚠️" [ref=e204] [cursor=pointer]: + - generic [ref=e205] [cursor=pointer]: Dishwashers + - generic [ref=e206] [cursor=pointer]: ⚠️ + - button "Door-to-Door Sales Workers, News & Street Vendors, & Related Workers ⚠️" [ref=e207] [cursor=pointer]: + - generic [ref=e208] [cursor=pointer]: Door-to-Door Sales Workers, News & Street Vendors, & Related Workers + - generic [ref=e209] [cursor=pointer]: ⚠️ + - button "Educational, Guidance, & Career Counselors & Advisors" [ref=e210] [cursor=pointer]: + - generic [ref=e211] [cursor=pointer]: Educational, Guidance, & Career Counselors & Advisors + - button "Helpers--Painters, Paperhangers, Plasterers, & Stucco Masons ⚠️" [ref=e212] [cursor=pointer]: + - generic [ref=e213] [cursor=pointer]: Helpers--Painters, Paperhangers, Plasterers, & Stucco Masons + - generic [ref=e214] [cursor=pointer]: ⚠️ + - button "Hospitalists" [ref=e215] [cursor=pointer]: + - generic [ref=e216] [cursor=pointer]: Hospitalists + - button "Low Vision Therapists, Orientation & Mobility Specialists, & Vision Rehabilitation Therapists" [ref=e217] [cursor=pointer]: + - generic [ref=e218] [cursor=pointer]: Low Vision Therapists, Orientation & Mobility Specialists, & Vision Rehabilitation Therapists + - button "Maids & Housekeeping Cleaners ⚠️" [ref=e219] [cursor=pointer]: + - generic [ref=e220] [cursor=pointer]: Maids & Housekeeping Cleaners + - generic [ref=e221] [cursor=pointer]: ⚠️ + - button "Nurse Midwives" [ref=e222] [cursor=pointer]: + - generic [ref=e223] [cursor=pointer]: Nurse Midwives + - button "Special Education Teachers, Preschool" [ref=e224] [cursor=pointer]: + - generic [ref=e225] [cursor=pointer]: Special Education Teachers, Preschool + - button "Substance Abuse & Behavioral Disorder Counselors ⚠️" [ref=e226] [cursor=pointer]: + - generic [ref=e227] [cursor=pointer]: Substance Abuse & Behavioral Disorder Counselors + - generic [ref=e228] [cursor=pointer]: ⚠️ + - generic [ref=e229]: + - text: This page includes information from + - link "O*NET OnLine" [ref=e230] [cursor=pointer]: + - /url: https://www.onetcenter.org + - text: by the U.S. Department of Labor, Employment & Training Administration (USDOL/ETA). Used under the + - link "CC BY 4.0 license" [ref=e231] [cursor=pointer]: + - /url: https://creativecommons.org/licenses/by/4.0/ + - text: . **O*NET®** is a trademark of USDOL/ETA. Salary and employment data are enriched with resources from the + - link "Bureau of Labor Statistics" [ref=e232] [cursor=pointer]: + - /url: https://www.bls.gov + - text: and program information from the + - link "National Center for Education Statistics" [ref=e233] [cursor=pointer]: + - /url: https://nces.ed.gov + - text: . + - button "Open chat" [ref=e234] [cursor=pointer]: + - img [ref=e235] [cursor=pointer] +``` \ No newline at end of file diff --git a/test-results/09-comparison-duplicate-re-10630-uplicate-remove-and-persist-edge/test-failed-1.png b/test-results/09-comparison-duplicate-re-10630-uplicate-remove-and-persist-edge/test-failed-1.png new file mode 100644 index 0000000..6ab5028 Binary files /dev/null and b/test-results/09-comparison-duplicate-re-10630-uplicate-remove-and-persist-edge/test-failed-1.png differ diff --git a/test-results/09-comparison-duplicate-re-10630-uplicate-remove-and-persist-edge/video.webm b/test-results/09-comparison-duplicate-re-10630-uplicate-remove-and-persist-edge/video.webm new file mode 100644 index 0000000..9019e99 Binary files /dev/null and b/test-results/09-comparison-duplicate-re-10630-uplicate-remove-and-persist-edge/video.webm differ diff --git a/test-results/22-educational-programs--p-85b9a-chool-cards-survives-reload-edge/error-context.md b/test-results/22-educational-programs--p-85b9a-chool-cards-survives-reload-edge/error-context.md new file mode 100644 index 0000000..a34d051 --- /dev/null +++ b/test-results/22-educational-programs--p-85b9a-chool-cards-survives-reload-edge/error-context.md @@ -0,0 +1,34 @@ +# Page snapshot + +```yaml +- generic [ref=e3]: + - banner [ref=e4]: + - heading "AptivaAI - Career Guidance Platform" [level=1] [ref=e5] + - navigation [ref=e6]: + - button "Find Your Career" [ref=e8] [cursor=pointer] + - button "Preparing & UpSkilling for Your Career" [ref=e10] [cursor=pointer] + - button "Enhancing Your Career(Premium)" [ref=e12] [cursor=pointer]: + - text: Enhancing Your Career + - generic [ref=e13] [cursor=pointer]: (Premium) + - button "Retirement Planning (beta)(Premium)" [ref=e15] [cursor=pointer]: + - text: Retirement Planning (beta) + - generic [ref=e16] [cursor=pointer]: (Premium) + - button "Profile" [ref=e18] [cursor=pointer] + - generic [ref=e19]: + - button "Upgrade to Premium" [ref=e20] [cursor=pointer] + - button "Support" [ref=e21] [cursor=pointer] + - button "Logout" [ref=e22] [cursor=pointer] + - main [ref=e23]: + - generic [ref=e24]: + - heading "Educational Programs" [level=2] [ref=e25] + - paragraph [ref=e26]: "You have not selected a career yet. Please search for one below:" + - generic [ref=e27]: + - generic [ref=e28]: + - text: Search for Career + - generic [ref=e29]: "*" + - combobox "Start typing a career..." [ref=e31] + - paragraph [ref=e32]: Please pick from the dropdown when performing search. Our database is very comprehensive but can’t accommodate every job title—choose the closest match to what you’re searching for. + - paragraph [ref=e33]: After you pick a career, we’ll display matching educational programs. + - button "Open chat" [ref=e34] [cursor=pointer]: + - img [ref=e35] [cursor=pointer] +``` \ No newline at end of file diff --git a/test-results/22-educational-programs--p-85b9a-chool-cards-survives-reload-edge/test-failed-1.png b/test-results/22-educational-programs--p-85b9a-chool-cards-survives-reload-edge/test-failed-1.png new file mode 100644 index 0000000..3f0736c Binary files /dev/null and b/test-results/22-educational-programs--p-85b9a-chool-cards-survives-reload-edge/test-failed-1.png differ diff --git a/test-results/22-educational-programs--p-85b9a-chool-cards-survives-reload-edge/video.webm b/test-results/22-educational-programs--p-85b9a-chool-cards-survives-reload-edge/video.webm new file mode 100644 index 0000000..a12f390 Binary files /dev/null and b/test-results/22-educational-programs--p-85b9a-chool-cards-survives-reload-edge/video.webm differ diff --git a/test-results/23-educational-programs-se-a20f2-ted-to-paywall-non-premium--edge/error-context.md b/test-results/23-educational-programs-se-a20f2-ted-to-paywall-non-premium--edge/error-context.md new file mode 100644 index 0000000..a34d051 --- /dev/null +++ b/test-results/23-educational-programs-se-a20f2-ted-to-paywall-non-premium--edge/error-context.md @@ -0,0 +1,34 @@ +# Page snapshot + +```yaml +- generic [ref=e3]: + - banner [ref=e4]: + - heading "AptivaAI - Career Guidance Platform" [level=1] [ref=e5] + - navigation [ref=e6]: + - button "Find Your Career" [ref=e8] [cursor=pointer] + - button "Preparing & UpSkilling for Your Career" [ref=e10] [cursor=pointer] + - button "Enhancing Your Career(Premium)" [ref=e12] [cursor=pointer]: + - text: Enhancing Your Career + - generic [ref=e13] [cursor=pointer]: (Premium) + - button "Retirement Planning (beta)(Premium)" [ref=e15] [cursor=pointer]: + - text: Retirement Planning (beta) + - generic [ref=e16] [cursor=pointer]: (Premium) + - button "Profile" [ref=e18] [cursor=pointer] + - generic [ref=e19]: + - button "Upgrade to Premium" [ref=e20] [cursor=pointer] + - button "Support" [ref=e21] [cursor=pointer] + - button "Logout" [ref=e22] [cursor=pointer] + - main [ref=e23]: + - generic [ref=e24]: + - heading "Educational Programs" [level=2] [ref=e25] + - paragraph [ref=e26]: "You have not selected a career yet. Please search for one below:" + - generic [ref=e27]: + - generic [ref=e28]: + - text: Search for Career + - generic [ref=e29]: "*" + - combobox "Start typing a career..." [ref=e31] + - paragraph [ref=e32]: Please pick from the dropdown when performing search. Our database is very comprehensive but can’t accommodate every job title—choose the closest match to what you’re searching for. + - paragraph [ref=e33]: After you pick a career, we’ll display matching educational programs. + - button "Open chat" [ref=e34] [cursor=pointer]: + - img [ref=e35] [cursor=pointer] +``` \ No newline at end of file diff --git a/test-results/23-educational-programs-se-a20f2-ted-to-paywall-non-premium--edge/test-failed-1.png b/test-results/23-educational-programs-se-a20f2-ted-to-paywall-non-premium--edge/test-failed-1.png new file mode 100644 index 0000000..3f0736c Binary files /dev/null and b/test-results/23-educational-programs-se-a20f2-ted-to-paywall-non-premium--edge/test-failed-1.png differ diff --git a/test-results/23-educational-programs-se-a20f2-ted-to-paywall-non-premium--edge/video.webm b/test-results/23-educational-programs-se-a20f2-ted-to-paywall-non-premium--edge/video.webm new file mode 100644 index 0000000..6afee64 Binary files /dev/null and b/test-results/23-educational-programs-se-a20f2-ted-to-paywall-non-premium--edge/video.webm differ diff --git a/test-results/35-careersearech-arrowdown-4e4dd--suggestion-and-opens-modal-edge/error-context.md b/test-results/35-careersearech-arrowdown-4e4dd--suggestion-and-opens-modal-edge/error-context.md new file mode 100644 index 0000000..6d29ef0 --- /dev/null +++ b/test-results/35-careersearech-arrowdown-4e4dd--suggestion-and-opens-modal-edge/error-context.md @@ -0,0 +1,92 @@ +# Page snapshot + +```yaml +- generic [ref=e3]: + - banner [ref=e4]: + - heading "AptivaAI - Career Guidance Platform" [level=1] [ref=e5] + - navigation [ref=e6]: + - button "Find Your Career" [ref=e8] [cursor=pointer] + - button "Preparing & UpSkilling for Your Career" [ref=e10] [cursor=pointer] + - button "Enhancing Your Career(Premium)" [ref=e12] [cursor=pointer]: + - text: Enhancing Your Career + - generic [ref=e13] [cursor=pointer]: (Premium) + - button "Retirement Planning (beta)(Premium)" [ref=e15] [cursor=pointer]: + - text: Retirement Planning (beta) + - generic [ref=e16] [cursor=pointer]: (Premium) + - button "Profile" [ref=e18] [cursor=pointer] + - generic [ref=e19]: + - button "Upgrade to Premium" [ref=e20] [cursor=pointer] + - button "Support" [ref=e21] [cursor=pointer] + - button "Logout" [ref=e22] [cursor=pointer] + - main [ref=e23]: + - generic [ref=e24]: + - generic [ref=e25]: + - heading "Explore Careers - use these tools to find your best fit" [level=2] [ref=e26] + - generic [ref=e27]: + - generic [ref=e28]: + - text: Search for Career + - generic [ref=e29]: "*" + - combobox "Start typing a career..." [active] [ref=e31]: cu + - paragraph [ref=e32]: Please pick from the dropdown when performing search. Our database is very comprehensive but can’t accommodate every job title—choose the closest match to what you’re searching for. + - generic [ref=e33]: + - heading "Career Comparison" [level=2] [ref=e34] + - button "Edit priorities" [ref=e35] [cursor=pointer] + - table [ref=e36]: + - rowgroup [ref=e37]: + - row "Career interests meaning stability growth balance recognition Match Actions" [ref=e38]: + - cell "Career" [ref=e39] + - cell "interests" [ref=e40] + - cell "meaning" [ref=e41] + - cell "stability" [ref=e42] + - cell "growth" [ref=e43] + - cell "balance" [ref=e44] + - cell "recognition" [ref=e45] + - cell "Match" [ref=e46] + - cell "Actions" [ref=e47] + - rowgroup [ref=e48]: + - row "Amusement & Recreation Attendants 5 3 1 3 3 3 53.8% Remove Plan your Education/Skills" [ref=e49]: + - cell "Amusement & Recreation Attendants" [ref=e50] + - cell "5" [ref=e51] + - cell "3" [ref=e52] + - cell "1" [ref=e53] + - cell "3" [ref=e54] + - cell "3" [ref=e55] + - cell "3" [ref=e56] + - cell "53.8%" [ref=e57] + - cell "Remove Plan your Education/Skills" [ref=e58]: + - button "Remove" [ref=e59] [cursor=pointer] + - button "Plan your Education/Skills" [ref=e60] [cursor=pointer] + - generic [ref=e61]: + - combobox [ref=e62]: + - option "All Preparation Levels" [selected] + - option "Little or No Preparation" + - option "Some Preparation Needed" + - option "Medium Preparation Needed" + - option "Considerable Preparation Needed" + - option "Extensive Preparation Needed" + - combobox [ref=e63]: + - option "All Fit Levels" [selected] + - option "Best - Very Strong Match" + - option "Great - Strong Match" + - option "Good - Less Strong Match" + - button "Reload Career Suggestions" [ref=e64] [cursor=pointer] + - generic [ref=e65]: + - generic [ref=e66]: ⚠️ + - generic [ref=e67]: = May have limited data for this career path + - generic [ref=e69]: + - text: This page includes information from + - link "O*NET OnLine" [ref=e70] [cursor=pointer]: + - /url: https://www.onetcenter.org + - text: by the U.S. Department of Labor, Employment & Training Administration (USDOL/ETA). Used under the + - link "CC BY 4.0 license" [ref=e71] [cursor=pointer]: + - /url: https://creativecommons.org/licenses/by/4.0/ + - text: . **O*NET®** is a trademark of USDOL/ETA. Salary and employment data are enriched with resources from the + - link "Bureau of Labor Statistics" [ref=e72] [cursor=pointer]: + - /url: https://www.bls.gov + - text: and program information from the + - link "National Center for Education Statistics" [ref=e73] [cursor=pointer]: + - /url: https://nces.ed.gov + - text: . + - button "Open chat" [ref=e74] [cursor=pointer]: + - img [ref=e75] [cursor=pointer] +``` \ No newline at end of file diff --git a/test-results/35-careersearech-arrowdown-4e4dd--suggestion-and-opens-modal-edge/test-failed-1.png b/test-results/35-careersearech-arrowdown-4e4dd--suggestion-and-opens-modal-edge/test-failed-1.png new file mode 100644 index 0000000..21d5041 Binary files /dev/null and b/test-results/35-careersearech-arrowdown-4e4dd--suggestion-and-opens-modal-edge/test-failed-1.png differ diff --git a/test-results/35-careersearech-arrowdown-4e4dd--suggestion-and-opens-modal-edge/video.webm b/test-results/35-careersearech-arrowdown-4e4dd--suggestion-and-opens-modal-edge/video.webm new file mode 100644 index 0000000..ed2e9ae Binary files /dev/null and b/test-results/35-careersearech-arrowdown-4e4dd--suggestion-and-opens-modal-edge/video.webm differ diff --git a/test-results/42-billing-refresh-status--3afec-eads-and-updates-plan-label-edge/error-context.md b/test-results/42-billing-refresh-status--3afec-eads-and-updates-plan-label-edge/error-context.md new file mode 100644 index 0000000..76ed1da --- /dev/null +++ b/test-results/42-billing-refresh-status--3afec-eads-and-updates-plan-label-edge/error-context.md @@ -0,0 +1,22 @@ +# Page snapshot + +```yaml +- generic [ref=e3]: + - banner [ref=e4]: + - heading "AptivaAI - Career Guidance Platform" [level=1] [ref=e5] + - main [ref=e6]: + - generic [ref=e8]: + - heading "Sign In" [level=1] [ref=e9] + - paragraph [ref=e10]: Unexpected token 'T', "Too many r"... is not valid JSON + - generic [ref=e11]: + - textbox "Username" [ref=e12]: test_u202509111029199314 + - textbox "Password" [ref=e13]: P@ssw0rd!9314 + - button "Sign In" [active] [ref=e14] [cursor=pointer] + - generic [ref=e15]: + - paragraph [ref=e16]: + - text: Don’t have an account? + - link "Sign Up" [ref=e17] [cursor=pointer]: + - /url: /signup + - link "Forgot your password?" [ref=e19] [cursor=pointer]: + - /url: /forgot-password +``` \ No newline at end of file diff --git a/test-results/42-billing-refresh-status--3afec-eads-and-updates-plan-label-edge/test-failed-1.png b/test-results/42-billing-refresh-status--3afec-eads-and-updates-plan-label-edge/test-failed-1.png new file mode 100644 index 0000000..9073b58 Binary files /dev/null and b/test-results/42-billing-refresh-status--3afec-eads-and-updates-plan-label-edge/test-failed-1.png differ diff --git a/test-results/42-billing-refresh-status--3afec-eads-and-updates-plan-label-edge/video.webm b/test-results/42-billing-refresh-status--3afec-eads-and-updates-plan-label-edge/video.webm new file mode 100644 index 0000000..653191d Binary files /dev/null and b/test-results/42-billing-refresh-status--3afec-eads-and-updates-plan-label-edge/video.webm differ diff --git a/test-results/43-billing-paywall-Billing-42b46-yload-no-redirect-on-non-OK-edge/error-context.md b/test-results/43-billing-paywall-Billing-42b46-yload-no-redirect-on-non-OK-edge/error-context.md new file mode 100644 index 0000000..bbde334 --- /dev/null +++ b/test-results/43-billing-paywall-Billing-42b46-yload-no-redirect-on-non-OK-edge/error-context.md @@ -0,0 +1,23 @@ +# Page snapshot + +```yaml +- generic [ref=e3]: + - banner [ref=e4]: + - heading "AptivaAI - Career Guidance Platform" [level=1] [ref=e5] + - main [ref=e6]: + - generic [ref=e7]: + - generic [ref=e8]: Your session has expired. Please sign in again. + - generic [ref=e9]: + - heading "Sign In" [level=1] [ref=e10] + - generic [ref=e11]: + - textbox "Username" [ref=e12] + - textbox "Password" [ref=e13] + - button "Sign In" [ref=e14] [cursor=pointer] + - generic [ref=e15]: + - paragraph [ref=e16]: + - text: Don’t have an account? + - link "Sign Up" [ref=e17] [cursor=pointer]: + - /url: /signup + - link "Forgot your password?" [ref=e19] [cursor=pointer]: + - /url: /forgot-password +``` \ No newline at end of file diff --git a/test-results/43-billing-paywall-Billing-42b46-yload-no-redirect-on-non-OK-edge/test-failed-1.png b/test-results/43-billing-paywall-Billing-42b46-yload-no-redirect-on-non-OK-edge/test-failed-1.png new file mode 100644 index 0000000..a9552fe Binary files /dev/null and b/test-results/43-billing-paywall-Billing-42b46-yload-no-redirect-on-non-OK-edge/test-failed-1.png differ diff --git a/test-results/43-billing-paywall-Billing-42b46-yload-no-redirect-on-non-OK-edge/video.webm b/test-results/43-billing-paywall-Billing-42b46-yload-no-redirect-on-non-OK-edge/video.webm new file mode 100644 index 0000000..4f25d40 Binary files /dev/null and b/test-results/43-billing-paywall-Billing-42b46-yload-no-redirect-on-non-OK-edge/video.webm differ diff --git a/test-results/43-billing-paywall-Billing-c23dd-g-anchors-render-Back-works-edge/error-context.md b/test-results/43-billing-paywall-Billing-c23dd-g-anchors-render-Back-works-edge/error-context.md new file mode 100644 index 0000000..bbde334 --- /dev/null +++ b/test-results/43-billing-paywall-Billing-c23dd-g-anchors-render-Back-works-edge/error-context.md @@ -0,0 +1,23 @@ +# Page snapshot + +```yaml +- generic [ref=e3]: + - banner [ref=e4]: + - heading "AptivaAI - Career Guidance Platform" [level=1] [ref=e5] + - main [ref=e6]: + - generic [ref=e7]: + - generic [ref=e8]: Your session has expired. Please sign in again. + - generic [ref=e9]: + - heading "Sign In" [level=1] [ref=e10] + - generic [ref=e11]: + - textbox "Username" [ref=e12] + - textbox "Password" [ref=e13] + - button "Sign In" [ref=e14] [cursor=pointer] + - generic [ref=e15]: + - paragraph [ref=e16]: + - text: Don’t have an account? + - link "Sign Up" [ref=e17] [cursor=pointer]: + - /url: /signup + - link "Forgot your password?" [ref=e19] [cursor=pointer]: + - /url: /forgot-password +``` \ No newline at end of file diff --git a/test-results/43-billing-paywall-Billing-c23dd-g-anchors-render-Back-works-edge/test-failed-1.png b/test-results/43-billing-paywall-Billing-c23dd-g-anchors-render-Back-works-edge/test-failed-1.png new file mode 100644 index 0000000..a9552fe Binary files /dev/null and b/test-results/43-billing-paywall-Billing-c23dd-g-anchors-render-Back-works-edge/test-failed-1.png differ diff --git a/test-results/43-billing-paywall-Billing-c23dd-g-anchors-render-Back-works-edge/video.webm b/test-results/43-billing-paywall-Billing-c23dd-g-anchors-render-Back-works-edge/video.webm new file mode 100644 index 0000000..a3492f7 Binary files /dev/null and b/test-results/43-billing-paywall-Billing-c23dd-g-anchors-render-Back-works-edge/video.webm differ diff --git a/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-edge/error-context.md b/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-edge/error-context.md new file mode 100644 index 0000000..76ed1da --- /dev/null +++ b/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-edge/error-context.md @@ -0,0 +1,22 @@ +# Page snapshot + +```yaml +- generic [ref=e3]: + - banner [ref=e4]: + - heading "AptivaAI - Career Guidance Platform" [level=1] [ref=e5] + - main [ref=e6]: + - generic [ref=e8]: + - heading "Sign In" [level=1] [ref=e9] + - paragraph [ref=e10]: Unexpected token 'T', "Too many r"... is not valid JSON + - generic [ref=e11]: + - textbox "Username" [ref=e12]: test_u202509111029199314 + - textbox "Password" [ref=e13]: P@ssw0rd!9314 + - button "Sign In" [active] [ref=e14] [cursor=pointer] + - generic [ref=e15]: + - paragraph [ref=e16]: + - text: Don’t have an account? + - link "Sign Up" [ref=e17] [cursor=pointer]: + - /url: /signup + - link "Forgot your password?" [ref=e19] [cursor=pointer]: + - /url: /forgot-password +``` \ No newline at end of file diff --git a/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-edge/test-failed-1.png b/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-edge/test-failed-1.png new file mode 100644 index 0000000..9073b58 Binary files /dev/null and b/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-edge/test-failed-1.png differ diff --git a/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-edge/video.webm b/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-edge/video.webm new file mode 100644 index 0000000..f52013e Binary files /dev/null and b/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-edge/video.webm differ diff --git a/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-retry1/error-context.md b/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-retry1/error-context.md deleted file mode 100644 index bc73311..0000000 --- a/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-retry1/error-context.md +++ /dev/null @@ -1,50 +0,0 @@ -# Page snapshot - -```yaml -- generic [active] [ref=e1]: - - generic [ref=e2]: - - navigation "Navigation Bar" [ref=e3]: - - generic [ref=e4]: - - link "Home" [ref=e5] [cursor=pointer]: - - /url: / - - img [ref=e6] [cursor=pointer] - - link "Explore" [ref=e7] [cursor=pointer]: - - /url: /explore/repos - - link "Help" [ref=e8] [cursor=pointer]: - - /url: https://docs.gitea.com - - generic [ref=e9]: - - link "Register" [ref=e10] [cursor=pointer]: - - /url: /user/sign_up - - img [ref=e11] [cursor=pointer] - - text: Register - - link "Sign In" [ref=e13] [cursor=pointer]: - - /url: /user/login?redirect_to=%2fsignin - - img [ref=e14] [cursor=pointer] - - text: Sign In - - main "Page Not Found" [ref=e16]: - - generic [ref=e17]: - - img "404" [ref=e18] - - paragraph [ref=e19]: - - text: The page you are trying to reach either - - strong [ref=e20]: does not exist - - text: or - - strong [ref=e21]: you are not authorized - - text: to view it. - - group "Footer" [ref=e22]: - - contentinfo "About Software" [ref=e23]: - - link "Powered by Gitea" [ref=e24] [cursor=pointer]: - - /url: https://about.gitea.com - - text: "Version: 1.22.6 Page:" - - strong [ref=e25]: 2ms - - text: "Template:" - - strong [ref=e26]: 1ms - - group "Links" [ref=e27]: - - menu [ref=e28] [cursor=pointer]: - - generic [ref=e29] [cursor=pointer]: - - img [ref=e30] [cursor=pointer] - - text: English - - link "Licenses" [ref=e32] [cursor=pointer]: - - /url: /assets/licenses.txt - - link "API" [ref=e33] [cursor=pointer]: - - /url: /api/swagger -``` \ No newline at end of file diff --git a/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-retry1/test-failed-1.png b/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-retry1/test-failed-1.png deleted file mode 100644 index 302c688..0000000 Binary files a/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-retry1/test-failed-1.png and /dev/null differ diff --git a/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-retry1/trace.zip b/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-retry1/trace.zip deleted file mode 100644 index 4971870..0000000 Binary files a/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-retry1/trace.zip and /dev/null differ diff --git a/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-retry1/video.webm b/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-retry1/video.webm deleted file mode 100644 index 80a0d46..0000000 Binary files a/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id-retry1/video.webm and /dev/null differ diff --git a/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id/error-context.md b/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id/error-context.md deleted file mode 100644 index b01d5d3..0000000 --- a/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id/error-context.md +++ /dev/null @@ -1,50 +0,0 @@ -# Page snapshot - -```yaml -- generic [active] [ref=e1]: - - generic [ref=e2]: - - navigation "Navigation Bar" [ref=e3]: - - generic [ref=e4]: - - link "Home" [ref=e5] [cursor=pointer]: - - /url: / - - img [ref=e6] [cursor=pointer] - - link "Explore" [ref=e7] [cursor=pointer]: - - /url: /explore/repos - - link "Help" [ref=e8] [cursor=pointer]: - - /url: https://docs.gitea.com - - generic [ref=e9]: - - link "Register" [ref=e10] [cursor=pointer]: - - /url: /user/sign_up - - img [ref=e11] [cursor=pointer] - - text: Register - - link "Sign In" [ref=e13] [cursor=pointer]: - - /url: /user/login?redirect_to=%2fsignin - - img [ref=e14] [cursor=pointer] - - text: Sign In - - main "Page Not Found" [ref=e16]: - - generic [ref=e17]: - - img "404" [ref=e18] - - paragraph [ref=e19]: - - text: The page you are trying to reach either - - strong [ref=e20]: does not exist - - text: or - - strong [ref=e21]: you are not authorized - - text: to view it. - - group "Footer" [ref=e22]: - - contentinfo "About Software" [ref=e23]: - - link "Powered by Gitea" [ref=e24] [cursor=pointer]: - - /url: https://about.gitea.com - - text: "Version: 1.22.6 Page:" - - strong [ref=e25]: 8ms - - text: "Template:" - - strong [ref=e26]: 6ms - - group "Links" [ref=e27]: - - menu [ref=e28] [cursor=pointer]: - - generic [ref=e29] [cursor=pointer]: - - img [ref=e30] [cursor=pointer] - - text: English - - link "Licenses" [ref=e32] [cursor=pointer]: - - /url: /assets/licenses.txt - - link "API" [ref=e33] [cursor=pointer]: - - /url: /api/swagger -``` \ No newline at end of file diff --git a/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id/test-failed-1.png b/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id/test-failed-1.png deleted file mode 100644 index e976e33..0000000 Binary files a/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id/test-failed-1.png and /dev/null differ diff --git a/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id/video.webm b/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id/video.webm deleted file mode 100644 index 188f947..0000000 Binary files a/test-results/44-onboarding-e2e--p0-Onbo-00a6c--lands-on-career-roadmap-id/video.webm and /dev/null differ diff --git a/test-results/45a-career-profile--p1-Pro-0c766-it-title-and-save-→-roadmap-edge/error-context.md b/test-results/45a-career-profile--p1-Pro-0c766-it-title-and-save-→-roadmap-edge/error-context.md new file mode 100644 index 0000000..76ed1da --- /dev/null +++ b/test-results/45a-career-profile--p1-Pro-0c766-it-title-and-save-→-roadmap-edge/error-context.md @@ -0,0 +1,22 @@ +# Page snapshot + +```yaml +- generic [ref=e3]: + - banner [ref=e4]: + - heading "AptivaAI - Career Guidance Platform" [level=1] [ref=e5] + - main [ref=e6]: + - generic [ref=e8]: + - heading "Sign In" [level=1] [ref=e9] + - paragraph [ref=e10]: Unexpected token 'T', "Too many r"... is not valid JSON + - generic [ref=e11]: + - textbox "Username" [ref=e12]: test_u202509111029199314 + - textbox "Password" [ref=e13]: P@ssw0rd!9314 + - button "Sign In" [active] [ref=e14] [cursor=pointer] + - generic [ref=e15]: + - paragraph [ref=e16]: + - text: Don’t have an account? + - link "Sign Up" [ref=e17] [cursor=pointer]: + - /url: /signup + - link "Forgot your password?" [ref=e19] [cursor=pointer]: + - /url: /forgot-password +``` \ No newline at end of file diff --git a/test-results/45a-career-profile--p1-Pro-0c766-it-title-and-save-→-roadmap-edge/test-failed-1.png b/test-results/45a-career-profile--p1-Pro-0c766-it-title-and-save-→-roadmap-edge/test-failed-1.png new file mode 100644 index 0000000..9073b58 Binary files /dev/null and b/test-results/45a-career-profile--p1-Pro-0c766-it-title-and-save-→-roadmap-edge/test-failed-1.png differ diff --git a/test-results/45a-career-profile--p1-Pro-0c766-it-title-and-save-→-roadmap-edge/video.webm b/test-results/45a-career-profile--p1-Pro-0c766-it-title-and-save-→-roadmap-edge/video.webm new file mode 100644 index 0000000..c73793a Binary files /dev/null and b/test-results/45a-career-profile--p1-Pro-0c766-it-title-and-save-→-roadmap-edge/video.webm differ diff --git a/test-results/45a-career-profile--p1-Pro-0f340-e-→-roadmap-then-edit-title-edge/error-context.md b/test-results/45a-career-profile--p1-Pro-0f340-e-→-roadmap-then-edit-title-edge/error-context.md new file mode 100644 index 0000000..76ed1da --- /dev/null +++ b/test-results/45a-career-profile--p1-Pro-0f340-e-→-roadmap-then-edit-title-edge/error-context.md @@ -0,0 +1,22 @@ +# Page snapshot + +```yaml +- generic [ref=e3]: + - banner [ref=e4]: + - heading "AptivaAI - Career Guidance Platform" [level=1] [ref=e5] + - main [ref=e6]: + - generic [ref=e8]: + - heading "Sign In" [level=1] [ref=e9] + - paragraph [ref=e10]: Unexpected token 'T', "Too many r"... is not valid JSON + - generic [ref=e11]: + - textbox "Username" [ref=e12]: test_u202509111029199314 + - textbox "Password" [ref=e13]: P@ssw0rd!9314 + - button "Sign In" [active] [ref=e14] [cursor=pointer] + - generic [ref=e15]: + - paragraph [ref=e16]: + - text: Don’t have an account? + - link "Sign Up" [ref=e17] [cursor=pointer]: + - /url: /signup + - link "Forgot your password?" [ref=e19] [cursor=pointer]: + - /url: /forgot-password +``` \ No newline at end of file diff --git a/test-results/45a-career-profile--p1-Pro-0f340-e-→-roadmap-then-edit-title-edge/test-failed-1.png b/test-results/45a-career-profile--p1-Pro-0f340-e-→-roadmap-then-edit-title-edge/test-failed-1.png new file mode 100644 index 0000000..9073b58 Binary files /dev/null and b/test-results/45a-career-profile--p1-Pro-0f340-e-→-roadmap-then-edit-title-edge/test-failed-1.png differ diff --git a/test-results/45a-career-profile--p1-Pro-0f340-e-→-roadmap-then-edit-title-edge/video.webm b/test-results/45a-career-profile--p1-Pro-0f340-e-→-roadmap-then-edit-title-edge/video.webm new file mode 100644 index 0000000..59c59ea Binary files /dev/null and b/test-results/45a-career-profile--p1-Pro-0f340-e-→-roadmap-then-edit-title-edge/video.webm differ diff --git a/test-results/45b-financial-profile--p1--ff592--accept-alert-→-leaves-page-edge/error-context.md b/test-results/45b-financial-profile--p1--ff592--accept-alert-→-leaves-page-edge/error-context.md new file mode 100644 index 0000000..76ed1da --- /dev/null +++ b/test-results/45b-financial-profile--p1--ff592--accept-alert-→-leaves-page-edge/error-context.md @@ -0,0 +1,22 @@ +# Page snapshot + +```yaml +- generic [ref=e3]: + - banner [ref=e4]: + - heading "AptivaAI - Career Guidance Platform" [level=1] [ref=e5] + - main [ref=e6]: + - generic [ref=e8]: + - heading "Sign In" [level=1] [ref=e9] + - paragraph [ref=e10]: Unexpected token 'T', "Too many r"... is not valid JSON + - generic [ref=e11]: + - textbox "Username" [ref=e12]: test_u202509111029199314 + - textbox "Password" [ref=e13]: P@ssw0rd!9314 + - button "Sign In" [active] [ref=e14] [cursor=pointer] + - generic [ref=e15]: + - paragraph [ref=e16]: + - text: Don’t have an account? + - link "Sign Up" [ref=e17] [cursor=pointer]: + - /url: /signup + - link "Forgot your password?" [ref=e19] [cursor=pointer]: + - /url: /forgot-password +``` \ No newline at end of file diff --git a/test-results/45b-financial-profile--p1--ff592--accept-alert-→-leaves-page-edge/test-failed-1.png b/test-results/45b-financial-profile--p1--ff592--accept-alert-→-leaves-page-edge/test-failed-1.png new file mode 100644 index 0000000..9073b58 Binary files /dev/null and b/test-results/45b-financial-profile--p1--ff592--accept-alert-→-leaves-page-edge/test-failed-1.png differ diff --git a/test-results/45b-financial-profile--p1--ff592--accept-alert-→-leaves-page-edge/video.webm b/test-results/45b-financial-profile--p1--ff592--accept-alert-→-leaves-page-edge/video.webm new file mode 100644 index 0000000..7993308 Binary files /dev/null and b/test-results/45b-financial-profile--p1--ff592--accept-alert-→-leaves-page-edge/video.webm differ diff --git a/test-results/45c-college-profile--p1-Co-0f842-lan-autosuggest-degree-save-edge/error-context.md b/test-results/45c-college-profile--p1-Co-0f842-lan-autosuggest-degree-save-edge/error-context.md new file mode 100644 index 0000000..76ed1da --- /dev/null +++ b/test-results/45c-college-profile--p1-Co-0f842-lan-autosuggest-degree-save-edge/error-context.md @@ -0,0 +1,22 @@ +# Page snapshot + +```yaml +- generic [ref=e3]: + - banner [ref=e4]: + - heading "AptivaAI - Career Guidance Platform" [level=1] [ref=e5] + - main [ref=e6]: + - generic [ref=e8]: + - heading "Sign In" [level=1] [ref=e9] + - paragraph [ref=e10]: Unexpected token 'T', "Too many r"... is not valid JSON + - generic [ref=e11]: + - textbox "Username" [ref=e12]: test_u202509111029199314 + - textbox "Password" [ref=e13]: P@ssw0rd!9314 + - button "Sign In" [active] [ref=e14] [cursor=pointer] + - generic [ref=e15]: + - paragraph [ref=e16]: + - text: Don’t have an account? + - link "Sign Up" [ref=e17] [cursor=pointer]: + - /url: /signup + - link "Forgot your password?" [ref=e19] [cursor=pointer]: + - /url: /forgot-password +``` \ No newline at end of file diff --git a/test-results/45c-college-profile--p1-Co-0f842-lan-autosuggest-degree-save-edge/test-failed-1.png b/test-results/45c-college-profile--p1-Co-0f842-lan-autosuggest-degree-save-edge/test-failed-1.png new file mode 100644 index 0000000..9073b58 Binary files /dev/null and b/test-results/45c-college-profile--p1-Co-0f842-lan-autosuggest-degree-save-edge/test-failed-1.png differ diff --git a/test-results/45c-college-profile--p1-Co-0f842-lan-autosuggest-degree-save-edge/video.webm b/test-results/45c-college-profile--p1-Co-0f842-lan-autosuggest-degree-save-edge/video.webm new file mode 100644 index 0000000..77d07c5 Binary files /dev/null and b/test-results/45c-college-profile--p1-Co-0f842-lan-autosuggest-degree-save-edge/video.webm differ diff --git a/test-results/45c-college-profile--p1-Co-82149-ink-to-career-prompt-→-save-edge/error-context.md b/test-results/45c-college-profile--p1-Co-82149-ink-to-career-prompt-→-save-edge/error-context.md new file mode 100644 index 0000000..76ed1da --- /dev/null +++ b/test-results/45c-college-profile--p1-Co-82149-ink-to-career-prompt-→-save-edge/error-context.md @@ -0,0 +1,22 @@ +# Page snapshot + +```yaml +- generic [ref=e3]: + - banner [ref=e4]: + - heading "AptivaAI - Career Guidance Platform" [level=1] [ref=e5] + - main [ref=e6]: + - generic [ref=e8]: + - heading "Sign In" [level=1] [ref=e9] + - paragraph [ref=e10]: Unexpected token 'T', "Too many r"... is not valid JSON + - generic [ref=e11]: + - textbox "Username" [ref=e12]: test_u202509111029199314 + - textbox "Password" [ref=e13]: P@ssw0rd!9314 + - button "Sign In" [active] [ref=e14] [cursor=pointer] + - generic [ref=e15]: + - paragraph [ref=e16]: + - text: Don’t have an account? + - link "Sign Up" [ref=e17] [cursor=pointer]: + - /url: /signup + - link "Forgot your password?" [ref=e19] [cursor=pointer]: + - /url: /forgot-password +``` \ No newline at end of file diff --git a/test-results/45c-college-profile--p1-Co-82149-ink-to-career-prompt-→-save-edge/test-failed-1.png b/test-results/45c-college-profile--p1-Co-82149-ink-to-career-prompt-→-save-edge/test-failed-1.png new file mode 100644 index 0000000..9073b58 Binary files /dev/null and b/test-results/45c-college-profile--p1-Co-82149-ink-to-career-prompt-→-save-edge/test-failed-1.png differ diff --git a/test-results/45c-college-profile--p1-Co-82149-ink-to-career-prompt-→-save-edge/video.webm b/test-results/45c-college-profile--p1-Co-82149-ink-to-career-prompt-→-save-edge/video.webm new file mode 100644 index 0000000..f04cf9d Binary files /dev/null and b/test-results/45c-college-profile--p1-Co-82149-ink-to-career-prompt-→-save-edge/video.webm differ diff --git a/test-results/47-career-roadmap-and-coac-d94d5-panels-and-projection-chart-edge/error-context.md b/test-results/47-career-roadmap-and-coac-d94d5-panels-and-projection-chart-edge/error-context.md new file mode 100644 index 0000000..76ed1da --- /dev/null +++ b/test-results/47-career-roadmap-and-coac-d94d5-panels-and-projection-chart-edge/error-context.md @@ -0,0 +1,22 @@ +# Page snapshot + +```yaml +- generic [ref=e3]: + - banner [ref=e4]: + - heading "AptivaAI - Career Guidance Platform" [level=1] [ref=e5] + - main [ref=e6]: + - generic [ref=e8]: + - heading "Sign In" [level=1] [ref=e9] + - paragraph [ref=e10]: Unexpected token 'T', "Too many r"... is not valid JSON + - generic [ref=e11]: + - textbox "Username" [ref=e12]: test_u202509111029199314 + - textbox "Password" [ref=e13]: P@ssw0rd!9314 + - button "Sign In" [active] [ref=e14] [cursor=pointer] + - generic [ref=e15]: + - paragraph [ref=e16]: + - text: Don’t have an account? + - link "Sign Up" [ref=e17] [cursor=pointer]: + - /url: /signup + - link "Forgot your password?" [ref=e19] [cursor=pointer]: + - /url: /forgot-password +``` \ No newline at end of file diff --git a/test-results/47-career-roadmap-and-coac-d94d5-panels-and-projection-chart-edge/test-failed-1.png b/test-results/47-career-roadmap-and-coac-d94d5-panels-and-projection-chart-edge/test-failed-1.png new file mode 100644 index 0000000..9073b58 Binary files /dev/null and b/test-results/47-career-roadmap-and-coac-d94d5-panels-and-projection-chart-edge/test-failed-1.png differ diff --git a/test-results/47-career-roadmap-and-coac-d94d5-panels-and-projection-chart-edge/video.webm b/test-results/47-career-roadmap-and-coac-d94d5-panels-and-projection-chart-edge/video.webm new file mode 100644 index 0000000..4c7ad7f Binary files /dev/null and b/test-results/47-career-roadmap-and-coac-d94d5-panels-and-projection-chart-edge/video.webm differ diff --git a/test-results/52-premium-routes-unlock---aaf4b-reer-roadmap-are-accessible-edge/error-context.md b/test-results/52-premium-routes-unlock---aaf4b-reer-roadmap-are-accessible-edge/error-context.md new file mode 100644 index 0000000..2afc7bd --- /dev/null +++ b/test-results/52-premium-routes-unlock---aaf4b-reer-roadmap-are-accessible-edge/error-context.md @@ -0,0 +1,28 @@ +# Page snapshot + +```yaml +- generic [ref=e3]: + - banner [ref=e4]: + - heading "AptivaAI - Career Guidance Platform" [level=1] [ref=e5] + - navigation [ref=e6]: + - button "Find Your Career" [ref=e8] [cursor=pointer] + - button "Preparing & UpSkilling for Your Career" [ref=e10] [cursor=pointer] + - button "Enhancing Your Career(Premium)" [ref=e12] [cursor=pointer]: + - text: Enhancing Your Career + - generic [ref=e13] [cursor=pointer]: (Premium) + - button "Retirement Planning (beta)(Premium)" [ref=e15] [cursor=pointer]: + - text: Retirement Planning (beta) + - generic [ref=e16] [cursor=pointer]: (Premium) + - button "Profile" [ref=e18] [cursor=pointer] + - generic [ref=e19]: + - button "Support" [ref=e20] [cursor=pointer] + - button "Logout" [ref=e21] [cursor=pointer] + - main [ref=e22]: + - generic [ref=e23]: + - 'heading "Your plan: Premium" [level=2] [ref=e24]' + - paragraph [ref=e25]: Manage payment method, invoices or cancel anytime. + - button "Manage subscription" [ref=e26] [cursor=pointer] + - button "Back to app" [ref=e27] [cursor=pointer] + - button "Open chat" [ref=e28] [cursor=pointer]: + - img [ref=e29] [cursor=pointer] +``` \ No newline at end of file diff --git a/test-results/52-premium-routes-unlock---aaf4b-reer-roadmap-are-accessible-edge/test-failed-1.png b/test-results/52-premium-routes-unlock---aaf4b-reer-roadmap-are-accessible-edge/test-failed-1.png new file mode 100644 index 0000000..efdbbd3 Binary files /dev/null and b/test-results/52-premium-routes-unlock---aaf4b-reer-roadmap-are-accessible-edge/test-failed-1.png differ diff --git a/test-results/52-premium-routes-unlock---aaf4b-reer-roadmap-are-accessible-edge/video.webm b/test-results/52-premium-routes-unlock---aaf4b-reer-roadmap-are-accessible-edge/video.webm new file mode 100644 index 0000000..5a67765 Binary files /dev/null and b/test-results/52-premium-routes-unlock---aaf4b-reer-roadmap-are-accessible-edge/video.webm differ diff --git a/tests/e2e/01-signup.spec.mjs b/tests/e2e/01-signup.spec.mjs index cef9512..9a6cb70 100644 --- a/tests/e2e/01-signup.spec.mjs +++ b/tests/e2e/01-signup.spec.mjs @@ -8,7 +8,7 @@ function uniq() { } test.describe('@p0 SignUp → Journey select → Route', () => { - test.setTimeout(15000); // allow for slower first load + areas fetch + test.setTimeout(10000); // allow for slower first load + areas fetch test('create a new user via UI and persist creds for later specs', async ({ page }) => { const u = uniq(); diff --git a/tests/e2e/02-signin-landing.spec.mjs b/tests/e2e/02-signin-landing.spec.mjs index f2b7985..ac69a4c 100644 --- a/tests/e2e/02-signin-landing.spec.mjs +++ b/tests/e2e/02-signin-landing.spec.mjs @@ -4,7 +4,7 @@ import { test, expect } from '@playwright/test'; import { loadTestUser } from '../utils/testUser.js'; test.describe('@p0 SignIn → Landing', () => { - test.setTimeout(20000); + test.setTimeout(10000); test('signs in with persisted user and reaches SignInLanding', async ({ page }) => { const user = loadTestUser(); diff --git a/tests/e2e/06-career-explorer.search.spec.mjs b/tests/e2e/06-career-explorer.search.spec.mjs index 33fc15f..77a7674 100644 --- a/tests/e2e/06-career-explorer.search.spec.mjs +++ b/tests/e2e/06-career-explorer.search.spec.mjs @@ -3,7 +3,7 @@ import { test, expect } from '@playwright/test'; import { loadTestUser } from '../utils/testUser.js'; test.describe('@p1 Career Explorer — CareerSearch datalist', () => { - test.setTimeout(30000); + test.setTimeout(20000); test('datalist commit opens modal; Change resets input', async ({ page }) => { const user = loadTestUser(); diff --git a/tests/e2e/09-comparison-duplicate-remove.spec.mjs b/tests/e2e/09-comparison-duplicate-remove.spec.mjs index 81e8c56..105729b 100644 --- a/tests/e2e/09-comparison-duplicate-remove.spec.mjs +++ b/tests/e2e/09-comparison-duplicate-remove.spec.mjs @@ -3,7 +3,7 @@ import { test, expect } from '@playwright/test'; import { loadTestUser } from '../utils/testUser.js'; test.describe('@p0 Comparison: add → duplicate blocked → remove → persists', () => { - test.setTimeout(20000); + test.setTimeout(15000); test('add one, block duplicate, remove and persist', async ({ page }) => { const user = loadTestUser(); diff --git a/tests/e2e/10-priorities-modal.spec.mjs b/tests/e2e/10-priorities-modal.spec.mjs index 6fdbf2e..953ad38 100644 --- a/tests/e2e/10-priorities-modal.spec.mjs +++ b/tests/e2e/10-priorities-modal.spec.mjs @@ -3,7 +3,7 @@ import { test, expect } from '@playwright/test'; import { loadTestUser } from '../utils/testUser.js'; test.describe('@p0 Priorities modal — save & persist (current UI)', () => { - test.setTimeout(20000); + test.setTimeout(15000); test('open → choose answers → Save Answers → reload → same answers present', async ({ page }) => { const user = loadTestUser(); diff --git a/tests/e2e/11-forgot-password-ui.spec.mjs b/tests/e2e/11-forgot-password-ui.spec.mjs index 94d3643..8ab3233 100644 --- a/tests/e2e/11-forgot-password-ui.spec.mjs +++ b/tests/e2e/11-forgot-password-ui.spec.mjs @@ -4,7 +4,7 @@ import { test, expect } from '@playwright/test'; import { loadTestUser } from '../utils/testUser.js'; test.describe('@p0 Forgot Password — exact UI flow', () => { - test.setTimeout(20000); + test.setTimeout(15000); test('SignIn → Forgot → invalid email blocked → valid submit shows success copy', async ({ page }) => { const user = loadTestUser(); diff --git a/tests/e2e/12-reset-password.spec.mjs b/tests/e2e/12-reset-password.spec.mjs index 6c8aba6..e5314a6 100644 --- a/tests/e2e/12-reset-password.spec.mjs +++ b/tests/e2e/12-reset-password.spec.mjs @@ -2,7 +2,7 @@ import { test, expect } from '@playwright/test'; test.describe('@p0 Reset Password — exact UI flow', () => { - test.setTimeout(20000); + test.setTimeout(15000); test('mismatch passwords → inline error, no request', async ({ page }) => { // Route with a token param (the component checks presence only) diff --git a/tests/e2e/13-premium-route-guard.spec.mjs b/tests/e2e/13-premium-route-guard.spec.mjs index d2a8ffe..0c779af 100644 --- a/tests/e2e/13-premium-route-guard.spec.mjs +++ b/tests/e2e/13-premium-route-guard.spec.mjs @@ -3,7 +3,7 @@ import { test, expect } from '@playwright/test'; import { loadTestUser } from '../utils/testUser.js'; test.describe('@p0 PremiumRoute guard', () => { - test.setTimeout(20000); + test.setTimeout(15000); test('non-premium user is redirected to /paywall from premium routes', async ({ page }) => { const user = loadTestUser(); diff --git a/tests/e2e/14-session-expired-handler.spec.mjs b/tests/e2e/14-session-expired-handler.spec.mjs index a86a2c8..e186b55 100644 --- a/tests/e2e/14-session-expired-handler.spec.mjs +++ b/tests/e2e/14-session-expired-handler.spec.mjs @@ -2,7 +2,7 @@ import { test, expect } from '@playwright/test'; test.describe('@p0 SessionExpiredHandler', () => { - test.setTimeout(20000); + test.setTimeout(15000); test('unauth → protected route → /signin?session=expired + banner', async ({ page }) => { await page.context().clearCookies(); diff --git a/tests/e2e/15-support-modal.spec.mjs b/tests/e2e/15-support-modal.spec.mjs index f3c1453..3c9066f 100644 --- a/tests/e2e/15-support-modal.spec.mjs +++ b/tests/e2e/15-support-modal.spec.mjs @@ -3,7 +3,7 @@ import { test, expect } from '@playwright/test'; import { loadTestUser } from '../utils/testUser.js'; test.describe('@p0 Support modal — open/close', () => { - test.setTimeout(20000); + test.setTimeout(15000); test('header Support opens modal and can be closed', async ({ page }) => { const user = loadTestUser(); diff --git a/tests/e2e/16-paywall-cta.spec.mjs b/tests/e2e/16-paywall-cta.spec.mjs index c4f77bc..fa58be2 100644 --- a/tests/e2e/16-paywall-cta.spec.mjs +++ b/tests/e2e/16-paywall-cta.spec.mjs @@ -3,7 +3,7 @@ import { test, expect } from '@playwright/test'; import { loadTestUser } from '../utils/testUser.js'; test.describe('@p0 Paywall CTA', () => { - test.setTimeout(20000); + test.setTimeout(15000); test('Upgrade to Premium visible on non-premium pages and navigates to /paywall', async ({ page }) => { const user = loadTestUser(); diff --git a/tests/e2e/17-support-submit.spec.mjs b/tests/e2e/17-support-submit.spec.mjs index ff47059..4e604c5 100644 --- a/tests/e2e/17-support-submit.spec.mjs +++ b/tests/e2e/17-support-submit.spec.mjs @@ -3,7 +3,7 @@ import { test, expect } from '@playwright/test'; import { loadTestUser } from '../utils/testUser.js'; test.describe('@p0 Support — submit ticket', () => { - test.setTimeout(20000); + test.setTimeout(15000); test('open → fill form → submit → success (network or UI)', async ({ page }) => { const user = loadTestUser(); diff --git a/tests/e2e/18-nav-menus.spec.mjs b/tests/e2e/18-nav-menus.spec.mjs index 817028a..3e922f3 100644 --- a/tests/e2e/18-nav-menus.spec.mjs +++ b/tests/e2e/18-nav-menus.spec.mjs @@ -3,7 +3,7 @@ import { test, expect } from '@playwright/test'; import { loadTestUser } from '../utils/testUser.js'; test.describe('@p0 Header nav menus', () => { - test.setTimeout(20000); + test.setTimeout(15000); test('Find Your Career menu → Career Explorer & Interest Inventory', async ({ page }) => { const u = loadTestUser(); diff --git a/tests/e2e/19-profile-gating.spec.mjs b/tests/e2e/19-profile-gating.spec.mjs index 4c68ee6..81b3ec2 100644 --- a/tests/e2e/19-profile-gating.spec.mjs +++ b/tests/e2e/19-profile-gating.spec.mjs @@ -3,7 +3,7 @@ import { test, expect } from '@playwright/test'; import { loadTestUser } from '../utils/testUser.js'; test.describe('@p0 Profile menu gating (non-premium)', () => { - test.setTimeout(20000); + test.setTimeout(15000); test('Career/College Profiles show disabled labels when user is not premium', async ({ page }) => { const u = loadTestUser(); diff --git a/tests/e2e/20-support-rate-limit.spec.mjs b/tests/e2e/20-support-rate-limit.spec.mjs index 47d9de3..60d8b3c 100644 --- a/tests/e2e/20-support-rate-limit.spec.mjs +++ b/tests/e2e/20-support-rate-limit.spec.mjs @@ -3,7 +3,7 @@ import { test, expect } from '@playwright/test'; import { loadTestUser } from '../utils/testUser.js'; test.describe('@p0 Support — burst rate limit', () => { - test.setTimeout(20000); + test.setTimeout(15000); test('rapid submissions eventually return 429 Too Many Requests', async ({ page }) => { const user = loadTestUser(); diff --git a/tests/e2e/21-support-auth-dedupe.spec.mjs b/tests/e2e/21-support-auth-dedupe.spec.mjs index 4e2f91d..e70c875 100644 --- a/tests/e2e/21-support-auth-dedupe.spec.mjs +++ b/tests/e2e/21-support-auth-dedupe.spec.mjs @@ -3,7 +3,7 @@ import { test, expect } from '@playwright/test'; import { loadTestUser } from '../utils/testUser.js'; test.describe('@p0 Support — auth + dedupe', () => { - test.setTimeout(20000); + test.setTimeout(15000); test('unauthenticated request is rejected (401)', async ({ page }) => { await page.context().clearCookies(); diff --git a/tests/e2e/22-educational-programs.spec.mjs b/tests/e2e/22-educational-programs.spec.mjs index 9fb682d..e2292c2 100644 --- a/tests/e2e/22-educational-programs.spec.mjs +++ b/tests/e2e/22-educational-programs.spec.mjs @@ -3,7 +3,7 @@ import { test, expect } from '@playwright/test'; import { loadTestUser } from '../utils/testUser.js'; test.describe('@p0 Educational Programs — handoff & page render', () => { - test.setTimeout(20000); + test.setTimeout(15000); test('handoff carries selectedCareer; page shows career title, KSA header and school cards; survives reload', async ({ page }) => { const user = loadTestUser(); diff --git a/tests/e2e/45a-career-profile.spec.mjs b/tests/e2e/45a-career-profile.spec.mjs new file mode 100644 index 0000000..a41c68d --- /dev/null +++ b/tests/e2e/45a-career-profile.spec.mjs @@ -0,0 +1,166 @@ +// @ts-check +import { test, expect } from '@playwright/test'; +import { loadTestUser } from '../utils/testUser.js'; + +// Grab the first input immediately following a label that matches text +// Use stable name-based locators (matches your component code) +const byName = (page, name) => page.locator(`input[name="${name}"]`).first(); + +// Fill a date input reliably (type=date => yyyy-mm-dd; else mm/dd/yyyy) +async function fillDateField(ctrl, iso = '2025-09-01', us = '09/01/2025') { + const type = (await ctrl.getAttribute('type')) || ''; + if (type.toLowerCase() === 'date') { + await ctrl.fill(iso); // browser renders mm/dd/yyyy + } else { + await ctrl.scrollIntoViewIfNeeded(); + await ctrl.click({ force: true }); + await ctrl.fill(''); + await ctrl.type(us, { delay: 15 }); + } +} + +test.describe('@p1 Profile — Career editor (44a)', () => { + test.setTimeout(20000); + test('Create new career from list → save → roadmap, then edit title', async ({ page }) => { + const u = loadTestUser(); + + // Premium gate + await page.route( + /\/api\/user-profile\?fields=.*(firstname|is_premium|is_pro_premium).*/i, + r => r.fulfill({ status: 200, contentType: 'application/json', + body: JSON.stringify({ firstname: 'Tester', is_premium: 1, is_pro_premium: 0 }) }) + ); + + // Stub /api/careers/search to return a real career from your dataset (Compliance Managers) + await page.route(/\/api\/careers\/search\?*/i, async route => { + const url = new URL(route.request().url()); + const q = (url.searchParams.get('query') || '').toLowerCase(); + const list = q.includes('compliance') + ? [{ title: 'Compliance Managers', soc_code: '11-9199.02', cip_codes: ['52.0304'] }] + : []; + await route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify(list) + }); + }); + + // List fetch on /profile/careers (allow real backend later, so don't pin to []) + await page.route('**/api/premium/career-profile/all', route => route.fallback()); + + // Accept POST save (UI create flow) + let createdId = null; + await page.route('**/api/premium/career-profile', async route => { + if (route.request().method() === 'POST') { + createdId = crypto.randomUUID(); + await route.fulfill({ + status: 200, contentType: 'application/json', + body: JSON.stringify({ career_profile_id: createdId }) + }); + } else { + await route.fallback(); + } + }); + + // Sign in + await page.context().clearCookies(); + await page.goto('/signin', { waitUntil: 'domcontentloaded' }); + await page.getByPlaceholder('Username', { exact: true }).fill(u.username); + await page.getByPlaceholder('Password', { exact: true }).fill(u.password); + await page.getByRole('button', { name: /^Sign In$/ }).click(); + await page.waitForURL('**/signin-landing**', { timeout: 15000 }); + + // Go to list and click + New Career Profile + await page.goto('/profile/careers', { waitUntil: 'domcontentloaded' }); + await page.getByRole('button', { name: '+ New Career Profile' }).click(); + await page.waitForURL('**/profile/careers/new/edit', { timeout: 15000 }); + await expect(page.getByRole('heading', { name: /^New Career Profile$/i })) + .toBeVisible({ timeout: 15000 }); + await expect(page.locator('input[name="start_date"]').first()) + .toBeVisible({ timeout: 15000 }); + + // Choose career (exact placeholder in new-form) +const search = page.getByPlaceholder('Start typing a career...', { exact: true }); + await expect(search).toBeVisible({ timeout: 5000 }); + await search.click(); + const waitSearch = page.waitForResponse(r => /\/api\/careers\/search/i.test(r.url())); + await search.fill('Compliance Managers'); + await waitSearch; + await page.keyboard.press('Enter'); // commit + await expect(page.locator('input[disabled]')).toHaveValue('Compliance Managers', { timeout: 3000 }); + + // Save → roadmap + await page.getByRole('button', { name: /^Save$/ }).click(); + await expect(page).toHaveURL(/\/career-roadmap\/[a-z0-9-]+$/i, { timeout: 25000 }); + + // Navigate to edit that same profile and tweak title (proves list→edit wiring) + // Ensure future requests use real backend + await page.unroute('**/api/premium/career-profile/all').catch(() => {}); + await page.goto('/profile/careers', { waitUntil: 'domcontentloaded' }); + // wait for at least one row to appear then click its edit link + await expect.poll(async () => await page.getByRole('link', { name: /^edit$/i }).count(), { timeout: 5000 }).toBeGreaterThan(0); + + await page.getByRole('link', { name: /^edit$/i }).first().click(); + }); + + test('Edit title and save → roadmap', async ({ page, request }) => { + const u = loadTestUser(); + + // Stub the GET that edit page calls so fields populate deterministically + await page.route('**/api/premium/career-profile/*', async route => { + await route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({ + scenario_title: 'Existing Scenario', + career_name: 'Data Analyst', + soc_code: '15-2051.00', + status: 'current', + start_date: '2025-09-01', + retirement_start_date: null, + college_enrollment_status: '', + career_goals: '', + desired_retirement_income_monthly: '' + }) + }); + }); + + // PremiumRoute gate + await page.route( + /\/api\/user-profile\?fields=.*(firstname|is_premium|is_pro_premium).*/i, + r => r.fulfill({ status: 200, contentType: 'application/json', + body: JSON.stringify({ firstname: 'Tester', is_premium: 1, is_pro_premium: 0 }) }) + ); + + // Sign in + await page.context().clearCookies(); + await page.goto('/signin', { waitUntil: 'domcontentloaded' }); + await page.getByPlaceholder('Username', { exact: true }).fill(u.username); + await page.getByPlaceholder('Password', { exact: true }).fill(u.password); + await page.getByRole('button', { name: /^Sign In$/ }).click(); + await page.waitForURL('**/signin-landing**', { timeout: 15_000 }); + + // Seed a profile via backend, then go directly to its edit page + const resp = await request.post('/api/premium/career-profile', { + data: { career_name: 'Data Analyst', status: 'planned', start_date: '2025-09-01' } + }); + const { career_profile_id } = await resp.json(); + + await page.goto(`/profile/careers/${career_profile_id}/edit`, { waitUntil: 'domcontentloaded' }); + await expect(page.getByRole('heading', { name: /Edit Career Profile/i })).toBeVisible({ timeout: 15_000 }); + + // Title + const title = byName(page, 'scenario_title'); + const prev = (await title.inputValue().catch(() => 'Scenario')) || 'Scenario'; + await title.fill(prev + ' — test'); + + // Start date (supports type=date or text mm/dd/yyyy) + const start = byName(page, 'start_date'); + if ((await start.count()) > 0) { + await fillDateField(start, '2025-09-01', '09/01/2025'); + } + + await page.getByRole('button', { name: /^Save$/ }).click(); + await expect(page).toHaveURL(/\/career-roadmap\/[a-z0-9-]+$/i, { timeout: 25_000 }); + }); +}); diff --git a/tests/e2e/45b-financial-profile.spec.mjs b/tests/e2e/45b-financial-profile.spec.mjs new file mode 100644 index 0000000..19c83a5 --- /dev/null +++ b/tests/e2e/45b-financial-profile.spec.mjs @@ -0,0 +1,82 @@ +// tests/e2e/45b-financial-profile.spec.mjs +// @ts-check +import { test, expect } from '@playwright/test'; +import { loadTestUser } from '../utils/testUser.js'; + +const byName = (page, n) => page.locator(`input[name="${n}"]`).first(); +// Label → first following input (works even without for/id) +const inputAfterLabel = (page, labelRe) => + page.locator('label').filter({ hasText: labelRe }).first() + .locator('xpath=following::input[1]').first(); + +test.describe('@p1 Profile — Financial editor (45b)', () => { + test.setTimeout(45000); + + test('Save financial profile (accept alert) → leaves page', async ({ page }) => { + const u = loadTestUser(); + + // Premium gate + await page.route( + /\/api\/user-profile\?fields=.*(firstname|is_premium|is_pro_premium).*/i, + r => r.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({ firstname: 'Tester', is_premium: 1, is_pro_premium: 0 }) + }) + ); + + // Deterministic GET/POST for the form + await page.route('**/api/premium/financial-profile', async route => { + if (route.request().method() === 'GET') { + await route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({ + current_salary: 0, + additional_income: 0, + monthly_expenses: 0, + monthly_debt_payments: 0, + retirement_savings: 0, + emergency_fund: 0, + retirement_contribution: 0, + emergency_contribution: 0, + extra_cash_emergency_pct: 50, + extra_cash_retirement_pct: 50 + }) + }); + } else if (route.request().method() === 'POST') { + await route.fulfill({ status: 200, body: '{}' }); + } else { + await route.fallback(); + } + }); + + // Sign in + await page.context().clearCookies(); + await page.goto('/signin', { waitUntil: 'domcontentloaded' }); + await page.getByPlaceholder('Username', { exact: true }).fill(u.username); + await page.getByPlaceholder('Password', { exact: true }).fill(u.password); + await page.getByRole('button', { name: /^Sign In$/ }).click(); + await page.waitForURL('**/signin-landing**', { timeout: 15_000 }); + + // Go to form + await page.goto('/financial-profile', { waitUntil: 'domcontentloaded' }); + await expect(page.getByRole('heading', { name: /Edit\s*Your\s*Financial\s*Profile/i })) + .toBeVisible({ timeout: 15_000 }); + + // Fill minimal fields + await byName(page, 'currentSalary').fill('55000'); + + // This field has NO name attribute → select by label then first input + await inputAfterLabel(page, /Monthly\s*Living\s*Expenses/i).fill('1800'); + + await byName(page, 'monthlyDebtPayments').fill('200'); + await byName(page, 'extraCashEmergencyPct').fill('40'); // complements to 60 + + // Accept expected alert then leave page + page.once('dialog', d => d.accept().catch(() => {})); + await page.getByRole('button', { name: /^Save$/ }).click(); + + await expect(page).not.toHaveURL(/\/financial-profile$/i, { timeout: 20_000 }); + }); +}); diff --git a/tests/e2e/45c-college-profile.spec.mjs b/tests/e2e/45c-college-profile.spec.mjs new file mode 100644 index 0000000..f60a94e --- /dev/null +++ b/tests/e2e/45c-college-profile.spec.mjs @@ -0,0 +1,262 @@ +// @ts-check +import { test, expect } from '@playwright/test'; +import { loadTestUser } from '../utils/testUser.js'; + +const SCHOOL = 'Alabama A & M University'; +const PROGRAM = 'Agriculture, General.'; +const DEGREE = "Bachelor's Degree"; + +async function fillDateField(ctrl, iso = '2027-06-01', us = '06/01/2027') { + const type = (await ctrl.getAttribute('type')) || ''; + if (type.toLowerCase() === 'date') { + await ctrl.fill(iso); + } else { + await ctrl.scrollIntoViewIfNeeded(); + await ctrl.click({ force: true }); + await ctrl.fill(''); + await ctrl.type(us, { delay: 15 }); + } +} + +async function commitAutosuggest(page, input, text) { + await input.click(); + await input.fill(text); + await page.keyboard.press('ArrowDown').catch(() => {}); + await page.keyboard.press('Enter').catch(() => {}); + await input.blur(); +} + +test.describe('@p1 College-Profile (45c)', () => { + test.setTimeout(20000); + + test('Create new college plan from list (with link-to-career prompt) → save', async ({ page, request }) => { + const u = loadTestUser(); + + // Premium gate + await page.route( + /\/api\/user-profile\?fields=.*(firstname|is_premium|is_pro_premium).*/i, + r => r.fulfill({ status: 200, contentType: 'application/json', + body: JSON.stringify({ firstname: 'Tester', is_premium: 1, is_pro_premium: 0 }) }) + ); + + // Seed a minimal Career Profile (needed for the prompt dropdown) + const scen = await request.post('/api/premium/career-profile', { + data: { career_name: 'Teaching Assistants, Postsecondary', status: 'planned', start_date: '2025-09-01' } + }); + const { career_profile_id } = await scen.json(); + + // Deterministic autosuggest + degree + tuition + await page.route(/\/api\/schools\/suggest\?*/i, async route => { + await route.fulfill({ status: 200, contentType: 'application/json', + body: JSON.stringify([{ name: 'Alabama A & M University', unitId: 100654 }]) }); + }); + await page.route(/\/api\/programs\/suggest\?*/i, async route => { + await route.fulfill({ status: 200, contentType: 'application/json', + body: JSON.stringify([{ program: 'Agriculture, General.' }]) }); + }); + await page.route(/\/api\/programs\/types\?*/i, async route => { + await route.fulfill({ status: 200, contentType: 'application/json', + body: JSON.stringify({ types: ["Bachelor's Degree"] }) }); + }); + await page.route(/\/api\/tuition\/estimate\?*/i, async route => { + await route.fulfill({ status: 200, contentType: 'application/json', + body: JSON.stringify({ estimate: 17220 }) }); + }); + + // Accept POST save + await page.route('**/api/premium/college-profile', async route => { + if (route.request().method() === 'POST') { + await route.fulfill({ status: 200, body: JSON.stringify({ ok: true }) }); + } else { + await route.fallback(); + } + }); + + // Sign in + await page.context().clearCookies(); + await page.goto('/signin', { waitUntil: 'domcontentloaded' }); + await page.getByPlaceholder('Username', { exact: true }).fill(u.username); + await page.getByPlaceholder('Password', { exact: true }).fill(u.password); + await page.getByRole('button', { name: /^Sign In$/ }).click(); + await page.waitForURL('**/signin-landing**', { timeout: 15000 }); + + // List → + New College Plan (expect link-to-career prompt) + await page.goto('/profile/college', { waitUntil: 'domcontentloaded' }); + await page.getByRole('button', { name: '+ New College Plan' }).click(); + // The prompt is a labeled box; target the