dev1/tests/e2e/40-educational-programs-distance-filter.spec.mjs
2025-09-18 13:26:16 +00:00

141 lines
5.0 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// @ts-nocheck
import { test, expect } from '@playwright/test';
import { loadTestUser } from '../utils/testUser.js';
test.describe('@p1 Educational Programs — distance filter (with geocode + schools stubs)', () => {
test.setTimeout(20000);
test('Distance (max) narrows results when ZIP is present', async ({ page }) => {
const u = loadTestUser();
// ---- Stubs ----
// 1) Profile ZIP/state so distance can be computed (match any query suffix)
await page.route('**/api/user-profile**', async route => {
await route.fulfill({
status: 200, contentType: 'application/json',
body: JSON.stringify({ zipcode: '30301', state: 'GA', area: 'Atlanta, GA' })
});
});
// 2) Geocode ZIP → lat/lng (actual endpoint used by clientGeocodeZip)
await page.route('https://maps.googleapis.com/maps/api/geocode/json**', async route => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
status: 'OK',
results: [
{ geometry: { location: { lat: 33.7495, lng: -84.3883 } } }
]
})
});
});
// 3) Schools list for CIP codes (cover common paths)
const schools = [
// near Atlanta (~35 mi)
{
INSTNM: 'Atlanta Tech College',
CIPDESC: 'Data Analytics',
CREDDESC: 'Certificate',
'In_state cost': '5000',
'Out_state cost': '7000',
LATITUDE: '33.80',
LONGITUD: '-84.39',
Website: 'atl.tech.edu',
UNITID: '1001',
State: 'GA'
},
// far (Chicago, ~590 mi)
{
INSTNM: 'Chicago State',
CIPDESC: 'Data Analytics',
CREDDESC: 'Bachelor',
'In_state cost': '6000',
'Out_state cost': '8000',
LATITUDE: '41.8781',
LONGITUD: '-87.6298',
Website: 'chicago.state.edu',
UNITID: '2002',
State: 'IL'
}
];
const fulfillSchools = async (route) => {
await route.fulfill({
status: 200, contentType: 'application/json',
body: JSON.stringify(schools)
});
};
await page.route('**/api/**schools**', fulfillSchools);
await page.route('**/api/**program**', fulfillSchools);
// 4) Avoid premium KSA latency: return empty quickly
await page.route('**/api/premium/ksa/**', async route => {
await route.fulfill({
status: 200, contentType: 'application/json',
body: JSON.stringify({ data: { knowledge: [], skills: [], abilities: [] } })
});
});
// ---- Sign in ----
await page.context().clearCookies();
await page.goto('/signin', { waitUntil: 'networkidle' });
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 });
// Seed selectedCareer so Programs loads without Explorer handoff
await page.evaluate(() => {
localStorage.setItem('selectedCareer', JSON.stringify({
title: 'Data Analyst',
soc_code: '15-2051.00',
cip_code: ['11.0802', '04.0201']
}));
});
// ---- Go to Programs ----
await page.goto('/educational-programs', { waitUntil: 'networkidle' });
// Wait for cards to render
const cards = page.locator('div.rounded.border.p-3.text-sm');
await expect(cards.first()).toBeVisible({ timeout: 30000 });
// Confirm we have at least one card up front
const countBefore = await cards.count();
expect(countBefore).toBeGreaterThan(0);
// Set Distance (max) to a small number to keep only the ATL card
const distanceInput = page.getByLabel(/Distance \(max\)/i);
await expect(distanceInput).toBeVisible();
await distanceInput.fill('10');
// ensure onChange/onBlur handlers fire
await distanceInput.press('Enter').catch(() => {});
await distanceInput.blur().catch(() => {});
await page.waitForTimeout(200); // small debounce cushion
// Trigger change — many components require blur or Enter
await distanceInput.press('Enter').catch(() => {});
await distanceInput.blur().catch(() => {});
// After applying Distance(max)=10, the Chicago card should disappear
// (dont rely on count; assert by card names)
await expect
.poll(async () => {
const names = await page
.locator('div.rounded.border.p-3.text-sm strong')
.allInnerTexts()
.catch(() => []);
const anyVisible = names.length > 0;
const hasChicago = names.some(n => /chicago/i.test(n));
return anyVisible && !hasChicago;
}, { timeout: 20000 })
.toBeTruthy();
// And at least one visible card should be the ATL school
const namesAfter = await page
.locator('div.rounded.border.p-3.text-sm strong')
.allInnerTexts()
.catch(() => []);
expect(namesAfter.some(n => /atlanta/i.test(n))).toBeTruthy();
});
});