Spaces:
Sleeping
Sleeping
File size: 5,362 Bytes
f6213fc | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | const { test, expect } = require('playwright/test');
const transparentPng = Buffer.from(
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+/p9sAAAAASUVORK5CYII=',
'base64',
);
test.beforeEach(async ({ page }) => {
await page.route('https://*.tile.openstreetmap.org/**', (route) => route.fulfill({
status: 200,
contentType: 'image/png',
body: transparentPng,
}));
});
function collectBrowserErrors(page) {
const errors = [];
page.on('pageerror', (error) => errors.push(error.message));
page.on('console', (message) => {
if (message.type() === 'error') errors.push(message.text());
});
return errors;
}
function demoSelect(page) {
return page.locator('.deliveries-field').filter({ hasText: 'Demo Data' }).locator('select');
}
function routingSelect(page) {
return page.locator('.deliveries-field').filter({ hasText: 'Routing Mode' }).locator('select');
}
test('boots the real deliveries app and serves required browser assets', async ({ page, request }) => {
const errors = collectBrowserErrors(page);
await expect(request.get('/health')).resolves.toBeOK();
await expect(request.get('/sf/sf.js')).resolves.toBeOK();
await expect(request.get('/sf/modules/sf-map.js')).resolves.toBeOK();
await expect(request.get('/app.js')).resolves.toBeOK();
await expect(request.get('/sf-config.json')).resolves.toBeOK();
await page.goto('/');
await expect(page).toHaveTitle('SolverForge Deliveries');
await expect(page.getByText('Retained delivery-route optimization with route previews')).toBeVisible();
await expect(page.locator('#sfStatusText')).toHaveText('Ready');
await expect(page.locator('.sf-constraint-dot')).toHaveCount(4);
for (const tab of ['Overview', 'By Vehicle', 'By Delivery', 'Data', 'REST API']) {
await expect(page.getByRole('tab', { name: tab })).toBeVisible();
}
await expect(demoSelect(page)).toHaveValue('PHILADELPHIA');
await expect(routingSelect(page)).toHaveValue('road_network');
await expect(page.getByText('PHILADELPHIA 路 road network 路 82 deliveries 路 10 vehicles')).toBeVisible();
await expect(page.locator('.deliveries-list__row')).toHaveCount(10);
await expect(page.locator('#deliveries-map')).toBeVisible();
await expect(page.locator('.sf-marker-vehicle')).toHaveCount(10);
await expect(page.locator('.sf-marker-visit')).toHaveCount(82);
expect(errors).toEqual([]);
});
test('switches datasets and exposes delivery-specific app panels', async ({ page }) => {
const errors = collectBrowserErrors(page);
await page.goto('/');
await demoSelect(page).selectOption('HARTFORD');
await expect(page.getByText('HARTFORD 路 road network 路 50 deliveries 路 10 vehicles')).toBeVisible();
await expect(page.locator('.sf-marker-visit')).toHaveCount(50);
await demoSelect(page).selectOption('FIRENZE');
await expect(page.getByText('FIRENZE 路 road network 路 80 deliveries 路 10 vehicles')).toBeVisible();
await expect(page.locator('.sf-marker-visit')).toHaveCount(80);
await page.getByRole('tab', { name: 'Data' }).click();
await expect(page.getByRole('heading', { name: 'Draft Data' })).toBeVisible();
await expect(page.getByRole('heading', { name: 'Vehicles' })).toBeVisible();
await expect(page.getByRole('heading', { name: 'Deliveries' })).toBeVisible();
await expect(page.getByRole('button', { name: 'Recommend' }).first()).toBeVisible();
await expect(page.locator('button').filter({ hasText: /Add|Remove/ })).toHaveCount(0);
await page.getByRole('tab', { name: 'REST API' }).click();
await expect(page.getByRole('heading', { name: 'GET /jobs/{id}/routes?snapshot_revision={n}' })).toBeVisible();
await expect(page.getByRole('heading', { name: 'POST /recommendations/delivery-insertions' })).toBeVisible();
expect(errors).toEqual([]);
});
test('highlights a route without moving or zooming the map', async ({ page }) => {
const errors = collectBrowserErrors(page);
await page.goto('/');
await expect(page.locator('.sf-marker-visit')).toHaveCount(82);
await page.evaluate(() => {
window.__fitBoundsCalls = 0;
const originalFitBounds = window.L.Map.prototype.fitBounds;
window.L.Map.prototype.fitBounds = function (...args) {
window.__fitBoundsCalls += 1;
return originalFitBounds.apply(this, args);
};
});
const firstRoute = page.locator('.deliveries-list__row').first();
await firstRoute.click();
await expect(firstRoute).toHaveClass(/is-focused/);
await expect(firstRoute.getByRole('button')).toHaveText('Show All');
await expect.poll(() => page.evaluate(() => window.__fitBoundsCalls)).toBe(0);
expect(errors).toEqual([]);
});
test('starts a retained straight-line solve and returns control to the user', async ({ page }) => {
const errors = collectBrowserErrors(page);
await page.goto('/');
await routingSelect(page).selectOption('straight_line');
await page.locator('button').filter({ hasText: 'Solve' }).first().click();
await expect(page.locator('#sf-app')).toHaveAttribute('data-job-id', /.+/, { timeout: 10_000 });
const stopButton = page.locator('button').filter({ hasText: 'Stop' }).first();
if (await stopButton.isVisible()) {
await stopButton.click();
}
await expect(page.locator('button').filter({ hasText: 'Solve' }).first()).toBeVisible({ timeout: 15_000 });
expect(errors).toEqual([]);
});
|