forked from geolonia/embed
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhelper.ts
More file actions
155 lines (138 loc) · 5.03 KB
/
Copy pathhelper.ts
File metadata and controls
155 lines (138 loc) · 5.03 KB
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import { Page } from '@playwright/test';
export const TEST_URL = 'http://localhost:3000/e2e';
export const LOAD_TIMEOUT = 5000;
/** 地図コンテナと canvas の出現を待つ。既存テスト互換。 */
export async function waitForMapLoad(page: Page, selector = '.geolonia') {
await page.waitForSelector(selector);
await page.waitForSelector(`${selector} canvas`, { timeout: LOAD_TIMEOUT });
}
/** Maplibre Map の load + isStyleLoaded を待つ。スタイル依存テスト向け。 */
export async function waitForStyleLoad(page: Page, selector = '#map') {
await page.waitForFunction(
(sel) => {
const el = document.querySelector(sel) as any;
return !!(el && el.geoloniaMap && el.geoloniaMap.loaded() && el.geoloniaMap.isStyleLoaded());
},
selector,
{ timeout: LOAD_TIMEOUT },
);
}
/** container.geoloniaMap が生成済みか確認。 */
export async function hasMapInstance(page: Page, selector = '#map'): Promise<boolean> {
return page.evaluate((sel) => {
const el = document.querySelector(sel) as any;
return !!(el && el.geoloniaMap);
}, selector);
}
export async function getCenter(page: Page, selector = '#map'): Promise<{ lat: number; lng: number }> {
return page.evaluate((sel) => {
const el = document.querySelector(sel) as any;
const c = el.geoloniaMap.getCenter();
return { lat: c.lat, lng: c.lng };
}, selector);
}
export async function getZoom(page: Page, selector = '#map'): Promise<number> {
return page.evaluate((sel) => {
const el = document.querySelector(sel) as any;
return el.geoloniaMap.getZoom();
}, selector);
}
export async function getBearing(page: Page, selector = '#map'): Promise<number> {
return page.evaluate((sel) => {
const el = document.querySelector(sel) as any;
return el.geoloniaMap.getBearing();
}, selector);
}
export async function getPitch(page: Page, selector = '#map'): Promise<number> {
return page.evaluate((sel) => {
const el = document.querySelector(sel) as any;
return el.geoloniaMap.getPitch();
}, selector);
}
export async function getStyleLayerIds(page: Page, selector = '#map'): Promise<string[]> {
return page.evaluate((sel) => {
const el = document.querySelector(sel) as any;
return el.geoloniaMap.getStyle().layers.map((l: any) => l.id);
}, selector);
}
export async function hasLayer(page: Page, layerId: string, selector = '#map'): Promise<boolean> {
return page.evaluate(
({ sel, id }) => {
const el = document.querySelector(sel) as any;
return !!el.geoloniaMap.getLayer(id);
},
{ sel: selector, id: layerId },
);
}
export async function hasSource(page: Page, sourceId: string, selector = '#map'): Promise<boolean> {
return page.evaluate(
({ sel, id }) => {
const el = document.querySelector(sel) as any;
return !!el.geoloniaMap.getSource(id);
},
{ sel: selector, id: sourceId },
);
}
/**
* Geolonia のスタイル/タイル/スプライト等を最小レスポンスでモックする。
* テスト先頭の beforeEach で呼ぶ前提。
*
* 返すスタイルは layers=[background] のみのミニマル style v8。
* 認証URL検証など transformRequest の挙動は実リクエスト前にここで握る。
*/
export async function mockGeoloniaTiles(page: Page) {
// スタイル JSON (cdn.geolonia.com/style/...)
await page.route(/cdn\.geolonia\.com\/style\/.+\.json/, (route) =>
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
version: 8,
sources: {},
layers: [
{ id: 'background', type: 'background', paint: { 'background-color': '#cccccc' } },
],
}),
}),
);
// スプライト / グリフ / フォント関連は 404 でよい (background のみなので参照されない)
await page.route(/cdn\.geolonia\.com\/(sprite|glyph|font)/, (route) =>
route.fulfill({ status: 404, body: '' }),
);
// TileJSON
await page.route(/tileserver\.geolonia\.com\/.*/, (route) =>
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
tilejson: '2.2.0',
tiles: ['https://tiles.geolonia.com/{z}/{x}/{y}.pbf'],
minzoom: 0,
maxzoom: 14,
}),
}),
);
// ベクトルタイル
await page.route(/\.tiles\.geolonia\.com\/.*\.pbf/, (route) =>
route.fulfill({ status: 204, body: '' }),
);
// api.geolonia.com (legacy / permission check 等)
await page.route(/api\.geolonia\.com\/.*/, (route) =>
route.fulfill({ status: 200, contentType: 'application/json', body: '{}' }),
);
}
/**
* 指定 predicate にマッチしたリクエスト URL を記録する。
* 呼び出し時点で配列を返し、以降の page 操作中に push される。
* 認証パラメータ注入の検証などに使用。
*/
export function recordRequests(
page: Page,
predicate: (url: string) => boolean = () => true,
): string[] {
const urls: string[] = [];
page.on('request', (req) => {
if (predicate(req.url())) urls.push(req.url());
});
return urls;
}