Skip to content

Commit fe7faef

Browse files
committed
[Map] Add E2E tests
1 parent 5067140 commit fe7faef

File tree

12 files changed

+457
-154
lines changed

12 files changed

+457
-154
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { expect, test } from '@playwright/test';
2+
3+
test('Can render basic map', async ({ page }) => {
4+
await page.goto('/ux-map/basic?renderer=google');
5+
6+
await expect(await page.getByTestId('map')).toBeVisible();
7+
8+
// Since we can't test Google Maps rendering due to API costs, we only assert that Google Maps API is (wrongly) loaded
9+
await expect(await page.getByTestId('map')).toContainText('Oops! Something went wrong.');
10+
await expect(await page.getByTestId('map')).toContainText(
11+
"This page didn't load Google Maps correctly. See the JavaScript console for technical details."
12+
);
13+
});

src/Map/src/Bridge/Google/assets/test/browser/map_controller.test.ts

Lines changed: 0 additions & 71 deletions
This file was deleted.
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
import { expect, type Page, test } from '@playwright/test';
2+
3+
async function expectMapToBeVisible(page: Page) {
4+
await expect(await page.getByTestId('map')).toBeVisible();
5+
await expect(await page.getByTestId('map').locator('.leaflet-pane').first()).toBeAttached();
6+
await expect(await page.getByTestId('map').locator('.leaflet-control-container')).toBeAttached();
7+
}
8+
9+
async function expectOneInfoWindowToBeOpenedAndContainText(page: Page, text: string) {
10+
const popups = page.locator('.leaflet-popup');
11+
await expect(popups).toHaveCount(1);
12+
await expect(popups.first()).toBeInViewport();
13+
await expect(popups.first()).toContainText(text);
14+
}
15+
16+
test('Can render basic map', async ({ page }) => {
17+
await page.goto('/ux-map/basic?renderer=leaflet');
18+
await expectMapToBeVisible(page);
19+
});
20+
21+
test('Can render markers and fit bounds to marker', async ({ page }) => {
22+
await page.goto('/ux-map/with-markers-and-fit-bounds-to-markers?renderer=leaflet');
23+
await expectMapToBeVisible(page);
24+
25+
const markers = page.getByTestId('map').locator('.leaflet-marker-icon');
26+
await expect(markers, '2 markers should be present').toHaveCount(2);
27+
for (const marker of await markers.all()) {
28+
await expect(marker).toBeInViewport();
29+
}
30+
31+
await expect(markers.nth(0)).toHaveAttribute('title', 'Paris');
32+
await expect(markers.nth(1)).toHaveAttribute('title', 'Lyon');
33+
});
34+
35+
test('Can render markers, zoomed on Paris, Lyon marker should be hidden', async ({ page }) => {
36+
await page.goto('/ux-map/with-markers-and-zoomed-on-paris?renderer=leaflet');
37+
await expectMapToBeVisible(page);
38+
39+
// Ensure the two markers are rendered, but only the Paris marker should be visible in the viewport
40+
const markers = page.getByTestId('map').locator('.leaflet-marker-icon');
41+
await expect(markers).toHaveCount(2);
42+
await expect(markers.nth(0)).toHaveAttribute('title', 'Paris');
43+
await expect(markers.nth(0)).toBeInViewport();
44+
await expect(markers.nth(1)).toHaveAttribute('title', 'Lyon');
45+
await expect(markers.nth(1), 'The "Lyon" marker should not be visible').not.toBeInViewport();
46+
});
47+
48+
test('Can render markers and info windows', async ({ page }) => {
49+
await page.goto('/ux-map/with-markers-and-info-windows?renderer=leaflet');
50+
await expectMapToBeVisible(page);
51+
52+
const markers = page.getByTestId('map').locator('.leaflet-marker-icon');
53+
await expect(markers, '2 markers should be present').toHaveCount(2);
54+
for (const marker of await markers.all()) {
55+
await expect(marker).toBeInViewport();
56+
}
57+
58+
await expect(markers.nth(0)).toHaveAttribute('title', 'Paris');
59+
await expect(markers.nth(1)).toHaveAttribute('title', 'Lyon');
60+
61+
// Ensure only one popup is visible at a time, the popup for Paris should be opened by default
62+
await expectOneInfoWindowToBeOpenedAndContainText(page, 'Capital of France');
63+
64+
// Click on the Lyon marker to open its popup, the Paris popup should close
65+
await markers.nth(1).click();
66+
await expectOneInfoWindowToBeOpenedAndContainText(page, 'Famous for its gastronomy');
67+
});
68+
69+
test('Can render markers with custom icons', async ({ page }) => {
70+
await page.goto('/ux-map/with-markers-and-custom-icons?renderer=leaflet');
71+
await expectMapToBeVisible(page);
72+
73+
const markers = page.getByTestId('map').locator('.leaflet-marker-icon');
74+
await expect(markers, '3 markers should be present').toHaveCount(3);
75+
for (const marker of await markers.all()) {
76+
await expect(marker).toBeInViewport();
77+
}
78+
79+
await expect(markers.nth(0)).toHaveAttribute('title', 'Paris');
80+
expect(await markers.nth(0).innerHTML()).toEqual(
81+
'<svg viewBox="0 0 24 24" width="24" height="24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path fill="currentColor" d="M8.21 17c.44-.85.85-1.84 1.23-3H9v-2h1c.61-2.6 1-5.87 1-10h2c0 4.13.4 7.4 1 10h1v2h-.44c.38 1.16.79 2.15 1.23 3H17v2l2 3h-2.42c-.77-1.76-2.53-3-4.58-3s-3.81 1.24-4.58 3H5l2-3l-.03-2zm4.38-3h-1.18a22 22 0 0 1-1.13 3h3.44c-.4-.87-.79-1.87-1.13-3"></path></svg>'
82+
);
83+
84+
await expect(markers.nth(1)).toHaveAttribute('title', 'Lyon');
85+
expect(await markers.nth(1).innerHTML()).toEqual(
86+
'<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="M11 9H9V2H7v7H5V2H3v7c0 2.12 1.66 3.84 3.75 3.97V22h2.5v-9.03C11.34 12.84 13 11.12 13 9V2h-2zm5-3v8h2.5v8H21V2c-2.76 0-5 2.24-5 4"></path></svg>'
87+
);
88+
89+
await expect(markers.nth(2)).toHaveAttribute('title', 'Bordeaux');
90+
await expect(markers.nth(2)).toHaveAttribute(
91+
'src',
92+
'/assets/icons/mdi/glass-wine-48e2d5c0e18f9b07dab82e113ec7490e.svg'
93+
);
94+
});
95+
96+
test('Can render polygons', async ({ page }) => {
97+
await page.goto('/ux-map/with-polygons?renderer=leaflet');
98+
await expectMapToBeVisible(page);
99+
100+
const paths = page.getByTestId('map').locator('path.leaflet-interactive');
101+
await expect(paths, '2 polygons must be present').toHaveCount(2);
102+
await expect(paths.nth(0)).toHaveAttribute(
103+
'd',
104+
'M548 276L656 188L762 260L708 433L573 384zM615 352L696 354L678 236L640 250z'
105+
);
106+
await expect(paths.nth(1)).toHaveAttribute('d', 'M870 476L795 364L844 395L911 508z');
107+
108+
// Workaround for `paths.nth(0).click({ relative: { ... } })` which does not work, it tries to click the center of the polygon,
109+
// but since it's empty, the popup can't be opened.
110+
const firstPathBoundingBox = await paths.nth(0).boundingBox();
111+
await page.mouse.click(firstPathBoundingBox.x + 40, firstPathBoundingBox.y + 100);
112+
await expectOneInfoWindowToBeOpenedAndContainText(page, 'A weird shape on the France');
113+
114+
const secondPathBoundingBox = await paths.nth(1).boundingBox();
115+
await page.mouse.click(secondPathBoundingBox.x + 50, secondPathBoundingBox.y + 40);
116+
await expectOneInfoWindowToBeOpenedAndContainText(page, 'A polygon covering some of the main cities in Italy');
117+
});
118+
119+
test('Can render polylines', async ({ page }) => {
120+
await page.goto('/ux-map/with-polylines?renderer=leaflet');
121+
await expectMapToBeVisible(page);
122+
123+
const paths = page.getByTestId('map').locator('path.leaflet-interactive');
124+
await expect(paths, '2 polylines must be present').toHaveCount(2);
125+
await expect(paths.nth(0)).toHaveAttribute('d', 'M640 250L696 354L708 433L573 384');
126+
await expect(paths.nth(1)).toHaveAttribute('d', 'M548 276L551 306L603 302');
127+
128+
// Workaround for `paths.nth(0).click({ relative: { ... } })` which does not work, it tries to click the center of the polygon,
129+
// but since it's empty, the popup can't be opened.
130+
const firstPathBoundingBox = await paths.nth(0).boundingBox();
131+
await page.mouse.click(firstPathBoundingBox.x + 95, firstPathBoundingBox.y + 50);
132+
await expectOneInfoWindowToBeOpenedAndContainText(page, 'A line passing through Paris, Lyon, Marseille, Bordeaux');
133+
134+
const secondPathBoundingBox = await paths.nth(1).boundingBox();
135+
await page.mouse.click(secondPathBoundingBox.x + 5, secondPathBoundingBox.y + 25);
136+
await expectOneInfoWindowToBeOpenedAndContainText(page, 'A line passing through Rennes, Nantes and Tours');
137+
});
138+
139+
test('Can render circles', async ({ page }) => {
140+
await page.goto('/ux-map/with-circles?renderer=leaflet');
141+
await expectMapToBeVisible(page);
142+
143+
const paths = page.getByTestId('map').locator('path.leaflet-interactive');
144+
await expect(paths, '2 circles must be present').toHaveCount(2);
145+
await expect(paths.nth(0)).toHaveAttribute(
146+
'd',
147+
'M623.5256177777774,250.21082480695986a16,16 0 1,0 32,0 a16,16 0 1,0 -32,0 '
148+
);
149+
await expect(paths.nth(1)).toHaveAttribute(
150+
'd',
151+
'M687.0390399999997,354.0936387274919a9,9 0 1,0 18,0 a9,9 0 1,0 -18,0 '
152+
);
153+
154+
await paths.nth(0).click();
155+
await expectOneInfoWindowToBeOpenedAndContainText(page, 'A 50km radius circle centered on Paris');
156+
157+
await paths.nth(1).click();
158+
await expectOneInfoWindowToBeOpenedAndContainText(page, 'A 30km radius circle centered on Lyon');
159+
});
160+
161+
test('Can render rectangles', async ({ page }) => {
162+
await page.goto('/ux-map/with-rectangles?renderer=leaflet');
163+
await expectMapToBeVisible(page);
164+
165+
const paths = page.getByTestId('map').locator('path.leaflet-interactive');
166+
await expect(paths, '2 rectangles must be present').toHaveCount(2);
167+
await expect(paths.nth(0)).toHaveAttribute('d', 'M640 250L640 188L656 188L656 250z');
168+
await expect(paths.nth(1)).toHaveAttribute('d', 'M573 384L573 354L696 354L696 384z');
169+
170+
await paths.nth(0).click();
171+
await expectOneInfoWindowToBeOpenedAndContainText(page, 'A rectangle from Paris to Lille');
172+
173+
await paths.nth(1).click();
174+
await expectOneInfoWindowToBeOpenedAndContainText(page, 'A rectangle from Bordeaux to Lyon');
175+
});

src/Map/src/Bridge/Leaflet/assets/test/browser/map_controller.test.ts

Lines changed: 0 additions & 72 deletions
This file was deleted.
Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
ux_map:
22
# https://symfony.com/bundles/ux-map/current/index.html#available-renderers
3-
renderer: '%env(resolve:default::UX_MAP_DSN)%'
3+
renderer: '' # configured in Kernel.php
44
google_maps:
55
# define the default map id for all maps (https://developers.google.com/maps/documentation/get-map-id)
6-
default_map_id: null
6+
# @Kocal: one of my default ID Map ID for testing purpose
7+
default_map_id: '%env(resolve:default::GOOGLE_MAPS_DEFAULT_MAP_ID)%'

0 commit comments

Comments
 (0)