@maptiler/sdk 3.10.2-rc.2 → 3.11.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/README.md +233 -66
  2. package/dist/eslint.mjs +8 -0
  3. package/dist/maptiler-sdk.mjs +3512 -2464
  4. package/dist/maptiler-sdk.mjs.map +1 -1
  5. package/dist/src/ImageViewer/ImageViewer.d.ts +2 -2
  6. package/dist/src/Map.d.ts +42 -2
  7. package/dist/src/MaptilerAnimation/AnimationManager.d.ts +41 -0
  8. package/dist/src/MaptilerAnimation/MaptilerAnimation.d.ts +238 -0
  9. package/dist/src/MaptilerAnimation/animation-helpers.d.ts +183 -0
  10. package/dist/src/MaptilerAnimation/easing.d.ts +3 -0
  11. package/dist/src/MaptilerAnimation/index.d.ts +7 -0
  12. package/dist/src/MaptilerAnimation/types.d.ts +26 -0
  13. package/dist/src/custom-layers/AnimatedRouteLayer/AnimatedRouteLayer.d.ts +293 -0
  14. package/dist/src/custom-layers/AnimatedRouteLayer/index.d.ts +1 -0
  15. package/dist/src/custom-layers/CubemapLayer/CubemapLayer.d.ts +1 -1
  16. package/dist/src/index.d.ts +2 -0
  17. package/dist/src/utils/array.d.ts +1 -0
  18. package/dist/src/utils/json.d.ts +1 -0
  19. package/dist/src/utils/string.d.ts +1 -0
  20. package/e2e/global.d.ts +14 -1
  21. package/e2e/public/animated-route.geojson +82 -0
  22. package/e2e/public/animatedRouteLayer.html +24 -0
  23. package/e2e/public/haloSpace.html +25 -0
  24. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-0-chromium-linux.png +0 -0
  25. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-1-chromium-linux.png +0 -0
  26. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-10-chromium-linux.png +0 -0
  27. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-11-chromium-linux.png +0 -0
  28. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-12-chromium-linux.png +0 -0
  29. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-13-chromium-linux.png +0 -0
  30. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-14-chromium-linux.png +0 -0
  31. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-15-chromium-linux.png +0 -0
  32. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-16-chromium-linux.png +0 -0
  33. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-17-chromium-linux.png +0 -0
  34. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-18-chromium-linux.png +0 -0
  35. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-19-chromium-linux.png +0 -0
  36. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-2-chromium-linux.png +0 -0
  37. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-3-chromium-linux.png +0 -0
  38. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-4-chromium-linux.png +0 -0
  39. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-5-chromium-linux.png +0 -0
  40. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-6-chromium-linux.png +0 -0
  41. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-7-chromium-linux.png +0 -0
  42. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-8-chromium-linux.png +0 -0
  43. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-9-chromium-linux.png +0 -0
  44. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/halo-halo-catalogue-style-halo-constructor-override-chromium-linux.png +0 -0
  45. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/halo-halo-json-style-config-halo-constructor-override-chromium-linux.png +0 -0
  46. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/halo-halo-json-style-config-halo-rendered-chromium-linux.png +0 -0
  47. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/halo-halo-json-style-config-halo-rendered-chromium.png +0 -0
  48. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/halo-halo-json-style-config-halo-true-chromium-linux.png +0 -0
  49. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/halo-halo-no-style-config-halo-true-chromium-linux.png +0 -0
  50. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/halo-halo-remote-style-config-halo-constructor-override-chromium-linux.png +0 -0
  51. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/halo-halo-remote-style-config-halo-false-chromium-linux.png +0 -0
  52. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/halo-halo-remote-style-config-halo-true-chromium-linux.png +0 -0
  53. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/halo-halo-style-config-halo-json-default-chromium-linux.png +0 -0
  54. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/halo-halo-style-config-halo-json-default-chromium.png +0 -0
  55. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/halo-halo-style-config-halo-json-false-chromium-linux.png +0 -0
  56. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/halo-halo-style-config-halo-json-false-chromium.png +0 -0
  57. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/halo-halo-style-config-halo-json-valid-chromium-linux.png +0 -0
  58. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/halo-halo-style-config-halo-json-valid-chromium.png +0 -0
  59. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/halo-halo-style-config-halo-remote-valid-chromium-linux.png +0 -0
  60. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/space-space-catalogue-style-config-space-true-chromium-linux.png +0 -0
  61. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/space-space-catalogue-style-config-space-undefined-chromium-linux.png +0 -0
  62. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/space-space-json-style-config-space-true-chromium-linux.png +0 -0
  63. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/space-space-json-style-config-space-true-chromium.png +0 -0
  64. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/space-space-json-style-config-space-true-default-chromium-linux.png +0 -0
  65. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/space-space-json-style-config-space-true-default-chromium.png +0 -0
  66. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/space-space-style-config-constructor-undefined-with-json-style-config-chromium-linux.png +0 -0
  67. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/space-space-style-config-space-constructor-with-catalogue-style-config-chromium-linux.png +0 -0
  68. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/space-space-style-config-space-constructor-with-json-space-config-chromium-linux.png +0 -0
  69. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/space-space-style-config-space-constructor-with-json-space-config-chromium.png +0 -0
  70. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/space-space-style-config-space-false-with-json-style-config-chromium-linux.png +0 -0
  71. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/space-space-style-config-space-false-with-json-style-config-chromium.png +0 -0
  72. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/space-space-style-config-space-false-with-style-config-chromium-linux.png +0 -0
  73. package/e2e/snapshots/tests/haloSpace.test.ts-snapshots/space-space-style-config-space-true-no-style-config-chromium-linux.png +0 -0
  74. package/e2e/snapshots/tests/map-load.test.ts-snapshots/halo-halo-json-style-config-halo-rendered-chromium-linux.png +0 -0
  75. package/e2e/snapshots/tests/map-load.test.ts-snapshots/halo-halo-json-style-config-halo-true-chromium-linux.png +0 -0
  76. package/e2e/snapshots/tests/map-load.test.ts-snapshots/halo-halo-style-config-halo-json-default-chromium-linux.png +0 -0
  77. package/e2e/snapshots/tests/map-load.test.ts-snapshots/halo-halo-style-config-halo-json-false-chromium-linux.png +0 -0
  78. package/e2e/snapshots/tests/map-load.test.ts-snapshots/halo-halo-style-config-halo-json-valid-chromium-linux.png +0 -0
  79. package/e2e/snapshots/tests/map-load.test.ts-snapshots/space-space-json-style-config-space-true-chromium-linux.png +0 -0
  80. package/e2e/snapshots/tests/map-load.test.ts-snapshots/space-space-json-style-config-space-true-chromium.png +0 -0
  81. package/e2e/snapshots/tests/map-load.test.ts-snapshots/space-space-json-style-config-space-true-default-chromium-linux.png +0 -0
  82. package/e2e/snapshots/tests/map-load.test.ts-snapshots/space-space-style-config-space-constructor-with-json-space-config-chromium-linux.png +0 -0
  83. package/e2e/snapshots/tests/map-load.test.ts-snapshots/space-space-style-config-space-false-with-json-style-config-chromium-linux.png +0 -0
  84. package/e2e/snapshots/tests/rtlTextPlugin.test.ts-snapshots/halo-halo-json-style-config-halo-rendered-chromium-linux.png +0 -0
  85. package/e2e/snapshots/tests/rtlTextPlugin.test.ts-snapshots/halo-halo-json-style-config-halo-true-chromium-linux.png +0 -0
  86. package/e2e/snapshots/tests/rtlTextPlugin.test.ts-snapshots/halo-halo-style-config-halo-json-default-chromium-linux.png +0 -0
  87. package/e2e/snapshots/tests/rtlTextPlugin.test.ts-snapshots/halo-halo-style-config-halo-json-false-chromium-linux.png +0 -0
  88. package/e2e/snapshots/tests/rtlTextPlugin.test.ts-snapshots/halo-halo-style-config-halo-json-valid-chromium-linux.png +0 -0
  89. package/e2e/snapshots/tests/rtlTextPlugin.test.ts-snapshots/space-space-json-style-config-space-true-chromium-linux.png +0 -0
  90. package/e2e/snapshots/tests/rtlTextPlugin.test.ts-snapshots/space-space-json-style-config-space-true-default-chromium-linux.png +0 -0
  91. package/e2e/snapshots/tests/rtlTextPlugin.test.ts-snapshots/space-space-style-config-space-constructor-with-json-space-config-chromium-linux.png +0 -0
  92. package/e2e/snapshots/tests/rtlTextPlugin.test.ts-snapshots/space-space-style-config-space-false-with-json-style-config-chromium-linux.png +0 -0
  93. package/e2e/tests/AnimatedRouteLayer.test.ts +45 -0
  94. package/e2e/tests/consts.ts +0 -0
  95. package/e2e/tests/expected-results/animatedRouteLayer-1.json +202 -0
  96. package/e2e/tests/haloSpace.test.ts +809 -0
  97. package/e2e/tests/helpers/fetchGeojson.ts +21 -0
  98. package/e2e/tests/helpers/getMapInstanceForFixture.ts +87 -0
  99. package/e2e/tests/helpers/injectGlobalVariables.ts +13 -0
  100. package/e2e/tests/helpers/loadFixtureAndGetMapHandle.ts +46 -36
  101. package/e2e/tests/mocks/maptiler-style-space-halo-invalid.json +38 -0
  102. package/e2e/tests/mocks/maptiler-style-space-halo.json +41 -0
  103. package/e2e/tests/mocks/maptiler-style.json +1 -0
  104. package/e2e/tests/rtlTextPlugin.test.ts +3 -12
  105. package/e2e/tsconfig.json +1 -1
  106. package/eslint.config.mjs +8 -0
  107. package/package.json +11 -4
  108. package/playwright.config.ts +7 -2
  109. package/tsconfig.json +1 -1
  110. package/vitest-setup-tests.ts +16 -0
  111. package/e2e/snapshots/tests/rtlTextPlugin.test.ts-snapshots/rtlTextPlugin-active-chromium-linux.png +0 -0
  112. package/e2e/snapshots/tests/rtlTextPlugin.test.ts-snapshots/rtlTextPlugin-disabled-chromium-linux.png +0 -0
@@ -0,0 +1,809 @@
1
+ // eslint-disable @typescript-eslint/no-unsafe-argument
2
+ import { Browser, expect, test } from "@playwright/test";
3
+ import loadFixtureAndGetMapHandle, { LoadFixtureAndGetMapHandleOptions } from "./helpers/loadFixtureAndGetMapHandle";
4
+ import maptilerBaseStyle from "./mocks/maptiler-style.json" assert { type: "json" };
5
+ import maptilerStyleSpaceHalo from "./mocks/maptiler-style-space-halo.json" assert { type: "json" };
6
+ import maptilerStyleSpaceHaloInvalid from "./mocks/maptiler-style-space-halo-invalid.json" assert { type: "json" };
7
+ import { StyleSpecificationWithMetaData } from "../../src";
8
+
9
+ const basicStyleSpec: StyleSpecificationWithMetaData = maptilerBaseStyle as unknown as StyleSpecificationWithMetaData;
10
+ const styleSpecWithHaloSpace: StyleSpecificationWithMetaData = maptilerStyleSpaceHalo as unknown as StyleSpecificationWithMetaData;
11
+ const styleSpecWithHaloSpaceInvalid: StyleSpecificationWithMetaData = maptilerStyleSpaceHaloInvalid as unknown as StyleSpecificationWithMetaData;
12
+
13
+ test.setTimeout(60000);
14
+
15
+ async function setupPage(browser: Browser, fixtureOptions: Partial<LoadFixtureAndGetMapHandleOptions> = {}) {
16
+ const context = await browser.newContext();
17
+ const page = await context.newPage();
18
+
19
+ // @ts-expect-error - "Type instantiation is excessively deep and possibly infinite"
20
+ await page.addInitScript(
21
+ (styles: Record<string, StyleSpecificationWithMetaData>) => {
22
+ window.__pageObjects = {
23
+ ...window.__pageObjects,
24
+ ...styles,
25
+ };
26
+ },
27
+ { styleSpecWithHaloSpace, styleSpecWithHaloSpaceInvalid, basicStyleSpec },
28
+ );
29
+
30
+ await loadFixtureAndGetMapHandle({
31
+ fixture: "haloSpace",
32
+ page,
33
+ lazy: true,
34
+ ...fixtureOptions,
35
+ });
36
+
37
+ expect(await page.title()).toBe("MapTiler E2E Halo Space");
38
+
39
+ return page;
40
+ }
41
+
42
+ //#region Halo tests
43
+ test.describe("Halo", () => {
44
+ test("if catalogue style has no halo config and halo === true in constructor, the default is rendered", async ({ browser }) => {
45
+ const page = await setupPage(browser);
46
+
47
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
48
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
49
+ });
50
+
51
+ await page.evaluate(async () => {
52
+ await window.setFixtureWithConfig({
53
+ id: "halo-no-style-config-halo-true",
54
+ options: {
55
+ container: "map",
56
+ halo: true,
57
+ zoom: 3,
58
+ },
59
+ });
60
+ });
61
+
62
+ const data = await screenshotPromise;
63
+ await expect(page).toHaveScreenshot(`halo-${data.id}.png`, { timeout: 10000 });
64
+ });
65
+
66
+ test("if remote style has a halo config and halo === true in constructor, that remote style is rendered", async ({ browser }) => {
67
+ const page = await setupPage(browser, {
68
+ mockStyle: "maptiler-style-space-halo.json",
69
+ });
70
+
71
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
72
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
73
+ });
74
+
75
+ await page.evaluate(async () => {
76
+ await window.setFixtureWithConfig({
77
+ id: "halo-remote-style-config-halo-true",
78
+ options: {
79
+ style: "doesnt-matter",
80
+ container: "map",
81
+ halo: true,
82
+ zoom: 3,
83
+ },
84
+ });
85
+ });
86
+
87
+ const data = await screenshotPromise;
88
+ await expect(page).toHaveScreenshot(`halo-${data.id}.png`, { timeout: 10000 });
89
+ });
90
+
91
+ test("if remote style has halo config, but halo config is passed to constructor, the constructor option config is rendered", async ({ browser }) => {
92
+ const page = await setupPage(browser, {
93
+ mockStyle: "maptiler-style-space-halo.json",
94
+ });
95
+
96
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
97
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
98
+ });
99
+
100
+ await page.evaluate(async () => {
101
+ await window.setFixtureWithConfig({
102
+ id: "halo-remote-style-config-halo-constructor-override",
103
+ options: {
104
+ container: "map",
105
+ halo: {
106
+ scale: 2,
107
+ stops: [
108
+ [0.2, "transparent"],
109
+ [0.2, "blue"],
110
+ [0.4, "blue"],
111
+ [0.4, "transparent"],
112
+ ],
113
+ },
114
+ zoom: 3,
115
+ },
116
+ });
117
+ });
118
+
119
+ const data = await screenshotPromise;
120
+ await expect(page).toHaveScreenshot(`halo-${data.id}.png`, { timeout: 10000 });
121
+ });
122
+
123
+ test("if json passed to setStyle has halo config, that config is rendered", async ({ browser }) => {
124
+ const page = await setupPage(browser);
125
+
126
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
127
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
128
+ });
129
+
130
+ await page.evaluate(async () => {
131
+ await window.setFixtureWithConfig({
132
+ id: "halo-json-style-config-halo-rendered",
133
+ options: {
134
+ container: "map",
135
+ zoom: 3,
136
+ },
137
+ requiresScreenShot: false,
138
+ });
139
+
140
+ await window.setFixtureMapStyle(window.__pageObjects.styleSpecWithHaloSpace);
141
+ });
142
+
143
+ const data = await screenshotPromise;
144
+ await expect(page).toHaveScreenshot(`halo-${data.id}.png`, { timeout: 10000 });
145
+ });
146
+
147
+ test("if json passed to setStyle has no halo config, but constructor option is set to `true`, the default halo is rendered", async ({ browser }) => {
148
+ const page = await setupPage(browser);
149
+
150
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
151
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
152
+ });
153
+
154
+ await page.evaluate(async () => {
155
+ await window.setFixtureWithConfig({
156
+ id: "halo-style-config-halo-json-default",
157
+ options: {
158
+ style: "doesnt-matter",
159
+ container: "map",
160
+ zoom: 3,
161
+ halo: true,
162
+ },
163
+ });
164
+
165
+ await window.setFixtureMapStyle(window.__pageObjects.basicStyleSpec);
166
+ });
167
+
168
+ const data = await screenshotPromise;
169
+ await expect(page).toHaveScreenshot(`halo-${data.id}.png`, { timeout: 10000 });
170
+ });
171
+
172
+ test("if remote style has halo config, but halo === false in constructor, no halo is rendered", async ({ browser }) => {
173
+ const page = await setupPage(browser, {
174
+ mockStyle: "maptiler-style-space-halo.json",
175
+ });
176
+
177
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
178
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
179
+ });
180
+
181
+ await page.evaluate(async () => {
182
+ await window.setFixtureWithConfig({
183
+ id: "halo-remote-style-config-halo-false",
184
+ options: {
185
+ container: "map",
186
+ halo: false,
187
+ zoom: 3,
188
+ },
189
+ });
190
+ });
191
+
192
+ const data = await screenshotPromise;
193
+ await expect(page).toHaveScreenshot(`halo-${data.id}.png`, { timeout: 10000 });
194
+ });
195
+
196
+ test("if a valid json halo config is passed to setStyle, but halo === true or unset in constructor, the halo is rendered", async ({ browser }) => {
197
+ // Test implementation
198
+ const page = await setupPage(browser);
199
+
200
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
201
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
202
+ });
203
+
204
+ await page.evaluate(async () => {
205
+ await window.setFixtureWithConfig({
206
+ id: "halo-json-style-config-halo-true",
207
+ options: {
208
+ container: "map",
209
+ zoom: 3,
210
+ halo: true,
211
+ },
212
+ });
213
+
214
+ await window.setFixtureMapStyle(window.__pageObjects.styleSpecWithHaloSpace);
215
+ });
216
+
217
+ const data = await screenshotPromise;
218
+ await expect(page).toHaveScreenshot(`halo-${data.id}.png`, { timeout: 10000 });
219
+ });
220
+
221
+ test("if a valid json halo config is passed to setStyle, but halo === false in constructor, the halo is not rendered", async ({ browser }) => {
222
+ // Test implementation
223
+ const page = await setupPage(browser);
224
+
225
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
226
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
227
+ });
228
+
229
+ await page.evaluate(async () => {
230
+ await window.setFixtureWithConfig({
231
+ id: "halo-style-config-halo-json-false",
232
+ options: {
233
+ container: "map",
234
+ zoom: 3,
235
+ halo: false,
236
+ },
237
+ });
238
+
239
+ await window.setFixtureMapStyle(window.__pageObjects.styleSpecWithHaloSpace);
240
+ });
241
+
242
+ const data = await screenshotPromise;
243
+ await expect(page).toHaveScreenshot(`halo-${data.id}.png`, { timeout: 10000 });
244
+ });
245
+
246
+ test("when halo is set to valid halo spec in constructor, it overrides remote style halo spec", async ({ browser }) => {
247
+ const page = await setupPage(browser);
248
+
249
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
250
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
251
+ });
252
+
253
+ await page.evaluate(async () => {
254
+ await window.setFixtureWithConfig({
255
+ id: "halo-catalogue-style-halo-constructor-override",
256
+ options: {
257
+ container: "map",
258
+ zoom: 3,
259
+ halo: {
260
+ scale: 2,
261
+ stops: [
262
+ [0.2, "transparent"],
263
+ [0.2, "blue"],
264
+ [0.4, "blue"],
265
+ [0.4, "transparent"],
266
+ ],
267
+ },
268
+ style: "streets-v4",
269
+ },
270
+ });
271
+ });
272
+
273
+ const data = await screenshotPromise;
274
+ await expect(page).toHaveScreenshot(`halo-${data.id}.png`, { timeout: 10000 });
275
+ });
276
+
277
+ test("when halo is set to valid halo spec in constructor, it overrides json to setStyle halo spec", async ({ browser }) => {
278
+ const page = await setupPage(browser);
279
+
280
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
281
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
282
+ });
283
+
284
+ await page.evaluate(async () => {
285
+ await window.setFixtureWithConfig({
286
+ id: "halo-json-style-config-halo-constructor-override",
287
+ options: {
288
+ container: "map",
289
+ zoom: 3,
290
+ halo: {
291
+ scale: 2,
292
+ stops: [
293
+ [0.2, "transparent"],
294
+ [0.2, "blue"],
295
+ [0.4, "blue"],
296
+ [0.4, "transparent"],
297
+ ],
298
+ },
299
+ style: window.__pageObjects.styleSpecWithHaloSpace,
300
+ },
301
+ });
302
+ });
303
+
304
+ const data = await screenshotPromise;
305
+ await expect(page).toHaveScreenshot(`halo-${data.id}.png`, { timeout: 10000 });
306
+ });
307
+
308
+ test("when halo constructor option is left undefined, if remote style that includes halo config is selected, it is rendered", async ({ browser }) => {
309
+ const page = await setupPage(browser, {
310
+ mockStyle: "maptiler-style-space-halo.json",
311
+ });
312
+
313
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
314
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
315
+ });
316
+
317
+ await page.evaluate(async () => {
318
+ await window.setFixtureWithConfig({
319
+ id: "halo-style-config-halo-remote-valid",
320
+ options: {
321
+ container: "map",
322
+ zoom: 3,
323
+ },
324
+ });
325
+
326
+ await window.setFixtureMapStyle("doesnt-matter-as-it-will-be-mocked");
327
+ });
328
+
329
+ const data = await screenshotPromise;
330
+ await expect(page).toHaveScreenshot(`halo-${data.id}.png`, { timeout: 10000 });
331
+ });
332
+
333
+ test("when halo constructor option is left undefined, if json with valid halo config is passed to setStyle, it is rendered", async ({ browser }) => {
334
+ const page = await setupPage(browser);
335
+
336
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
337
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
338
+ });
339
+
340
+ await page.evaluate(async () => {
341
+ await window.setFixtureWithConfig({
342
+ id: "halo-style-config-halo-json-valid",
343
+ options: {
344
+ container: "map",
345
+ zoom: 3,
346
+ },
347
+ });
348
+
349
+ await window.setFixtureMapStyle(window.__pageObjects.styleSpecWithHaloSpace);
350
+ });
351
+
352
+ const data = await screenshotPromise;
353
+ await expect(page).toHaveScreenshot(`halo-${data.id}.png`, { timeout: 10000 });
354
+ });
355
+
356
+ test("when an invalid spec is passed to the constructor the console notifies the user of the incorrect spec", async ({ browser }) => {
357
+ const page = await setupPage(browser);
358
+
359
+ // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
360
+ await page.exposeFunction("notifyScreenshotStateReady", async (data: Record<string, TTestTransferData>) => {});
361
+
362
+ const expectedErrorMessage = `[RadialGradientLayer]: Invalid Halo specification:
363
+ - Properties \`hi\` are not supported.
364
+ - Halo \`scale\` property is not a number.
365
+ - Halo \`stops\` property is not an array of [number, string]`;
366
+
367
+ const consolePromise = page.waitForEvent("console", {
368
+ predicate: (msg) => msg.type() === "error" && msg.text().includes(expectedErrorMessage),
369
+ });
370
+
371
+ await page.evaluate(async () => {
372
+ await window.setFixtureWithConfig({
373
+ id: "halo-style-config-halo-invalid",
374
+ options: {
375
+ container: "map",
376
+ zoom: 3,
377
+ space: false,
378
+ halo: {
379
+ hi: "there",
380
+ // @ts-expect-error - invalid spec
381
+ stops: [0.2, "transparent"],
382
+ },
383
+ },
384
+ });
385
+ });
386
+
387
+ const consoleMsg = await consolePromise;
388
+ expect(consoleMsg.type()).toBe("error");
389
+ expect(consoleMsg.text()).toContain(expectedErrorMessage);
390
+ });
391
+
392
+ test("when an invalid spec is included in a catalogue style the console notifies the user of the incorrect spec", async ({ browser }) => {
393
+ const page = await setupPage(browser, {
394
+ mockStyle: "maptiler-style-space-halo-invalid.json",
395
+ });
396
+
397
+ // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
398
+ await page.exposeFunction("notifyScreenshotStateReady", async (_: Record<string, TTestTransferData>) => {});
399
+
400
+ const expectedErrorMessage = `[RadialGradientLayer]: Invalid Halo specification:
401
+ - Halo \`scale\` property is not a number.
402
+ - Halo \`stops\` property is not an array.`;
403
+
404
+ const consolePromise = page.waitForEvent("console", {
405
+ predicate: (msg) => msg.type() === "error" && msg.text().includes(expectedErrorMessage),
406
+ });
407
+
408
+ await page.evaluate(async () => {
409
+ await window.setFixtureWithConfig({
410
+ id: "halo-catalogue-style-config-halo-invalid",
411
+ options: {
412
+ container: "map",
413
+ zoom: 3,
414
+ space: false,
415
+ },
416
+ });
417
+ });
418
+
419
+ const consoleMsg = await consolePromise;
420
+ expect(consoleMsg.type()).toBe("error");
421
+ expect(consoleMsg.text()).toContain(expectedErrorMessage);
422
+ });
423
+
424
+ test("when an invalid spec is included in a json style the console notifies the user of the incorrect spec", async ({ browser }) => {
425
+ const page = await setupPage(browser);
426
+
427
+ // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
428
+ await page.exposeFunction("notifyScreenshotStateReady", async (_: Record<string, TTestTransferData>) => {});
429
+
430
+ const expectedErrorMessage = `[RadialGradientLayer]: Invalid Halo specification:
431
+ - Halo \`scale\` property is not a number.
432
+ - Halo \`stops\` property is not an array.`;
433
+
434
+ const consolePromise = page.waitForEvent("console", {
435
+ predicate: (msg) => msg.type() === "error" && msg.text().includes(expectedErrorMessage),
436
+ });
437
+
438
+ await page.evaluate(async () => {
439
+ await window.setFixtureWithConfig({
440
+ id: "halo-style-config-halo-json-invalid",
441
+ options: {
442
+ container: "map",
443
+ zoom: 3,
444
+ space: false,
445
+ },
446
+ });
447
+
448
+ await window.setFixtureMapStyle(window.__pageObjects.styleSpecWithHaloSpaceInvalid);
449
+ });
450
+
451
+ const consoleMsg = await consolePromise;
452
+ expect(consoleMsg.type()).toBe("error");
453
+ expect(consoleMsg.text()).toContain(expectedErrorMessage);
454
+ });
455
+ });
456
+
457
+ //#region Space tests
458
+ test.describe("Space", () => {
459
+ test("when space is set to true in constructor, if catalogue style has no space config, the default is rendered", async ({ browser }) => {
460
+ const page = await setupPage(browser, {
461
+ mockStyle: "maptiler-style.json",
462
+ });
463
+
464
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
465
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
466
+ });
467
+
468
+ await page.evaluate(async () => {
469
+ await window.setFixtureWithConfig({
470
+ id: "space-style-config-space-true-no-style-config",
471
+ options: {
472
+ container: "map",
473
+ space: true,
474
+ halo: false,
475
+ zoom: 3,
476
+ },
477
+ });
478
+ });
479
+
480
+ const data = await screenshotPromise;
481
+ await expect(page).toHaveScreenshot(`space-${data.id}.png`, { timeout: 10000 });
482
+ });
483
+
484
+ test("when space is set to true in constructor, if catalogue has a space config, that config is rendered", async ({ browser }) => {
485
+ const page = await setupPage(browser, {
486
+ mockStyle: "maptiler-style-space-halo.json",
487
+ });
488
+
489
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
490
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
491
+ });
492
+
493
+ await page.evaluate(async () => {
494
+ await window.setFixtureWithConfig({
495
+ id: "space-catalogue-style-config-space-true",
496
+ options: {
497
+ container: "map",
498
+ space: true,
499
+ halo: false,
500
+ zoom: 3,
501
+ },
502
+ });
503
+ });
504
+
505
+ const data = await screenshotPromise;
506
+ await expect(page).toHaveScreenshot(`space-${data.id}.png`, { timeout: 10000 });
507
+ });
508
+
509
+ test("when space is set to true in constructor, if json passed to setStyle has space config, that config is rendered", async ({ browser }) => {
510
+ const page = await setupPage(browser);
511
+
512
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
513
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
514
+ });
515
+
516
+ await page.evaluate(async () => {
517
+ await window.setFixtureWithConfig({
518
+ id: "space-json-style-config-space-true",
519
+ options: {
520
+ container: "map",
521
+ space: true,
522
+ halo: false,
523
+ zoom: 3,
524
+ },
525
+ });
526
+ await window.setFixtureMapStyle(window.__pageObjects.styleSpecWithHaloSpace);
527
+ });
528
+
529
+ const data = await screenshotPromise;
530
+ await expect(page).toHaveScreenshot(`space-${data.id}.png`, { timeout: 10000 });
531
+ });
532
+
533
+ test("when space is set to true in constructor, if json passed to setStyle has no space config, the default space is rendered", async ({ browser }) => {
534
+ const page = await setupPage(browser);
535
+
536
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
537
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
538
+ });
539
+
540
+ await page.evaluate(async () => {
541
+ await window.setFixtureWithConfig({
542
+ id: "space-json-style-config-space-true-default",
543
+ options: {
544
+ container: "map",
545
+ space: true,
546
+ halo: false,
547
+ zoom: 3,
548
+ },
549
+ });
550
+ await window.setFixtureMapStyle(window.__pageObjects.basicStyleSpec);
551
+ });
552
+
553
+ const data = await screenshotPromise;
554
+ await expect(page).toHaveScreenshot(`space-${data.id}.png`, { timeout: 10000 });
555
+ });
556
+
557
+ test("when space is set to false in constructor, if catalogue style has space config, it is ignored and no space is rendered", async ({ browser }) => {
558
+ const page = await setupPage(browser, {
559
+ mockStyle: "maptiler-style-space-halo.json",
560
+ });
561
+
562
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
563
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
564
+ });
565
+
566
+ await page.evaluate(async () => {
567
+ await window.setFixtureWithConfig({
568
+ id: "space-style-config-space-false-with-style-config",
569
+ options: {
570
+ container: "map",
571
+ space: false,
572
+ halo: false,
573
+ zoom: 3,
574
+ },
575
+ });
576
+ });
577
+
578
+ const data = await screenshotPromise;
579
+ await expect(page).toHaveScreenshot(`space-${data.id}.png`, { timeout: 10000 });
580
+ });
581
+
582
+ test("when space is set to false in constructor, if json is passed to setStyle, it is ignored and no space is rendered", async ({ browser }) => {
583
+ const page = await setupPage(browser);
584
+
585
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
586
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
587
+ });
588
+
589
+ await page.evaluate(async () => {
590
+ await window.setFixtureWithConfig({
591
+ id: "space-style-config-space-false-with-json-style-config",
592
+ options: {
593
+ container: "map",
594
+ space: false,
595
+ halo: false,
596
+ zoom: 3,
597
+ },
598
+ });
599
+ await window.setFixtureMapStyle(window.__pageObjects.styleSpecWithHaloSpace);
600
+ });
601
+
602
+ const data = await screenshotPromise;
603
+ await expect(page).toHaveScreenshot(`space-${data.id}.png`, { timeout: 10000 });
604
+ });
605
+
606
+ test("when space is set to valid space spec in constructor, it overrides catalogue space spec", async ({ browser }) => {
607
+ const page = await setupPage(browser, {
608
+ mockStyle: "maptiler-style-space-halo.json",
609
+ });
610
+
611
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
612
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
613
+ });
614
+
615
+ await page.evaluate(async () => {
616
+ await window.setFixtureWithConfig({
617
+ id: "space-style-config-space-constructor-with-catalogue-style-config",
618
+ options: {
619
+ container: "map",
620
+ space: {
621
+ color: "red",
622
+ preset: "stars",
623
+ },
624
+ halo: false,
625
+ zoom: 3,
626
+ },
627
+ });
628
+ });
629
+
630
+ const data = await screenshotPromise;
631
+ await expect(page).toHaveScreenshot(`space-${data.id}.png`, { timeout: 10000 });
632
+ });
633
+
634
+ test("when space is set to valid space spec in constructor, it overrides json to setStyle space spec", async ({ browser }) => {
635
+ const page = await setupPage(browser, {
636
+ mockStyle: "maptiler-style-space-halo.json",
637
+ });
638
+
639
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
640
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
641
+ });
642
+
643
+ await page.evaluate(async () => {
644
+ await window.setFixtureWithConfig({
645
+ id: "space-style-config-space-constructor-with-json-space-config",
646
+ options: {
647
+ container: "map",
648
+ space: {
649
+ color: "red",
650
+ preset: "stars",
651
+ },
652
+ halo: false,
653
+ zoom: 3,
654
+ },
655
+ });
656
+ await window.setFixtureMapStyle(window.__pageObjects.styleSpecWithHaloSpace);
657
+ });
658
+
659
+ const data = await screenshotPromise;
660
+ await expect(page).toHaveScreenshot(`space-${data.id}.png`, { timeout: 10000 });
661
+ });
662
+
663
+ test("when space constructor option is left undefined, if catalogue style is selected, it is rendered", async ({ browser }) => {
664
+ const page = await setupPage(browser, {
665
+ mockStyle: "maptiler-style-space-halo.json",
666
+ });
667
+
668
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
669
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
670
+ });
671
+
672
+ await page.evaluate(async () => {
673
+ await window.setFixtureWithConfig({
674
+ id: "space-catalogue-style-config-space-undefined",
675
+ options: {
676
+ container: "map",
677
+ zoom: 3,
678
+ halo: false,
679
+ style: "doesnt-matter-as-it-will-be-mocked",
680
+ },
681
+ });
682
+ });
683
+
684
+ const data = await screenshotPromise;
685
+ await expect(page).toHaveScreenshot(`space-${data.id}.png`, { timeout: 10000 });
686
+ });
687
+
688
+ test("when space constructor option is left undefined, if json passed to setStyle, it is rendered", async ({ browser }) => {
689
+ const page = await setupPage(browser, {
690
+ mockStyle: "maptiler-style.json",
691
+ });
692
+
693
+ const screenshotPromise = new Promise<Record<string, TTestTransferData>>((resolve) => {
694
+ void page.exposeFunction("notifyScreenshotStateReady", resolve);
695
+ });
696
+
697
+ await page.evaluate(async () => {
698
+ await window.setFixtureWithConfig({
699
+ id: "space-style-config-constructor-undefined-with-json-style-config",
700
+ options: {
701
+ container: "map",
702
+ zoom: 3,
703
+ halo: false,
704
+ },
705
+ requiresScreenShot: false,
706
+ });
707
+ await window.setFixtureMapStyle("doesnt-matter-as-it-will-be-mocked");
708
+ });
709
+
710
+ const data = await screenshotPromise;
711
+ await expect(page).toHaveScreenshot(`space-${data.id}.png`, { timeout: 10000 });
712
+ });
713
+
714
+ test("when an invalid spec is passed to the constructor, the console notifies the user of the incorrect spec", async ({ browser }) => {
715
+ const page = await setupPage(browser, {
716
+ mockStyle: "maptiler-style.json",
717
+ });
718
+
719
+ // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
720
+ await page.exposeFunction("notifyScreenshotStateReady", async (data: Record<string, TTestTransferData>) => {});
721
+
722
+ const expectedErrorMessage = `Error: [CubemapLayer]: Invalid cubemap specification:
723
+ - Space specification contains unsupported properties: \`not\`. Supported properties: \`color\`, \`preset\`, \`path\`, \`faces\`.`;
724
+
725
+ const consolePromise = page.waitForEvent("console", {
726
+ predicate: (msg) => msg.type() === "error" && msg.text().includes(expectedErrorMessage),
727
+ });
728
+
729
+ await page.evaluate(async () => {
730
+ await window.setFixtureWithConfig({
731
+ id: "space-constructor-config-space-invalid",
732
+ options: {
733
+ container: "map",
734
+ halo: false,
735
+ style: "doesn't-matter-as-it-will-be-mocked",
736
+ space: {
737
+ not: "a valid spec",
738
+ // @ts-expect-error - invalid spec
739
+ color: ["not", "an array"],
740
+ },
741
+ },
742
+ });
743
+ });
744
+ const consoleMsg = await consolePromise;
745
+ expect(consoleMsg.type()).toBe("error");
746
+ expect(consoleMsg.text()).toContain(expectedErrorMessage);
747
+ });
748
+
749
+ test("when an invalid spec is included in a catalogue style, the console notifies the user of the incorrect spec", async ({ browser }) => {
750
+ const page = await setupPage(browser, {
751
+ mockStyle: "maptiler-style-space-halo-invalid.json",
752
+ });
753
+
754
+ // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
755
+ await page.exposeFunction("notifyScreenshotStateReady", async (data: Record<string, TTestTransferData>) => {});
756
+
757
+ const expectedErrorMessage = `Error: [CubemapLayer]: Invalid cubemap specification:
758
+ - Space preset "3" is not a valid preset. Available presets: stars, space, milkyway, milkyway-subtle, milkyway-bright, milkyway-colored`;
759
+
760
+ const consolePromise = page.waitForEvent("console", {
761
+ predicate: (msg) => msg.type() === "error" && msg.text().includes(expectedErrorMessage),
762
+ });
763
+
764
+ await page.evaluate(async () => {
765
+ await window.setFixtureWithConfig({
766
+ id: "space-catalogue-style-config-space-invalid",
767
+ options: {
768
+ container: "map",
769
+ halo: false,
770
+ style: "doesn't-matter-as-it-will-be-mocked",
771
+ },
772
+ });
773
+ });
774
+ const consoleMsg = await consolePromise;
775
+ expect(consoleMsg.type()).toBe("error");
776
+ expect(consoleMsg.text()).toContain(expectedErrorMessage);
777
+ });
778
+
779
+ test("when an invalid spec is included in a json style, the console notifies the user of the incorrect spec", async ({ browser }) => {
780
+ const page = await setupPage(browser, {
781
+ mockStyle: "maptiler-style.json",
782
+ });
783
+
784
+ // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
785
+ await page.exposeFunction("notifyScreenshotStateReady", async (data: Record<string, TTestTransferData>) => {});
786
+
787
+ const expectedErrorMessage = `Error: [CubemapLayer]: Invalid cubemap specification:
788
+ - Space preset "3" is not a valid preset. Available presets: stars, space, milkyway, milkyway-subtle, milkyway-bright, milkyway-colored`;
789
+
790
+ const consolePromise = page.waitForEvent("console", {
791
+ predicate: (msg) => msg.type() === "error" && msg.text().includes(expectedErrorMessage),
792
+ });
793
+
794
+ await page.evaluate(async () => {
795
+ await window.setFixtureWithConfig({
796
+ id: "space-json-style-config-space-invalid",
797
+ options: {
798
+ container: "map",
799
+ halo: false,
800
+ style: "doesn't-matter-as-it-will-be-mocked",
801
+ },
802
+ });
803
+ await window.setFixtureMapStyle(window.__pageObjects.styleSpecWithHaloSpaceInvalid);
804
+ });
805
+ const consoleMsg = await consolePromise;
806
+ expect(consoleMsg.type()).toBe("error");
807
+ expect(consoleMsg.text()).toContain(expectedErrorMessage);
808
+ });
809
+ });