terra-draw 0.0.1-alpha.54 → 0.0.1-alpha.56

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 (34) hide show
  1. package/dist/common.d.ts +2 -2
  2. package/dist/geometry/transform/scale.d.ts +2 -2
  3. package/dist/modes/base.mode.d.ts +4 -4
  4. package/dist/modes/great-circle-snapping.behavior.d.ts +2 -1
  5. package/dist/modes/select/behaviors/drag-coordinate.behavior.d.ts +3 -2
  6. package/dist/modes/select/behaviors/drag-feature.behavior.d.ts +3 -2
  7. package/dist/modes/select/behaviors/drag-maintained-shape.behavior.d.ts +23 -0
  8. package/dist/modes/select/behaviors/midpoint.behavior.d.ts +2 -1
  9. package/dist/modes/select/behaviors/rotate-feature.behavior.d.ts +2 -1
  10. package/dist/modes/select/behaviors/scale-feature.behavior.d.ts +2 -1
  11. package/dist/modes/select/behaviors/selection-point.behavior.d.ts +5 -4
  12. package/dist/modes/select/select.mode.d.ts +2 -0
  13. package/dist/modes/snapping.behavior.d.ts +2 -1
  14. package/dist/store/spatial-index/spatial-index.d.ts +3 -3
  15. package/dist/store/store-feature-validation.d.ts +4 -3
  16. package/dist/store/store.d.ts +24 -13
  17. package/dist/terra-draw.cjs +1 -1
  18. package/dist/terra-draw.cjs.map +1 -1
  19. package/dist/terra-draw.d.ts +23 -5
  20. package/dist/terra-draw.modern.js +1 -1
  21. package/dist/terra-draw.modern.js.map +1 -1
  22. package/dist/terra-draw.module.js +1 -1
  23. package/dist/terra-draw.module.js.map +1 -1
  24. package/dist/terra-draw.umd.js +1 -1
  25. package/dist/terra-draw.umd.js.map +1 -1
  26. package/e2e/package-lock.json +591 -2
  27. package/e2e/package.json +6 -3
  28. package/e2e/playwright.config.ts +1 -1
  29. package/e2e/public/index.html +1 -1
  30. package/e2e/src/index.ts +1 -0
  31. package/e2e/tests/leaflet.spec.ts +100 -23
  32. package/e2e/tests/setup.ts +50 -2
  33. package/e2e/webpack.config.js +4 -6
  34. package/package.json +1 -1
package/e2e/package.json CHANGED
@@ -6,18 +6,21 @@
6
6
  "scripts": {
7
7
  "build": "webpack",
8
8
  "serve": "webpack serve",
9
- "test": "playwright test",
9
+ "test": "playwright test --workers=1",
10
+ "test:help": "playwright test --help",
10
11
  "test:ui": "playwright test --ui --headed"
11
12
  },
12
13
  "author": "James Milner",
13
14
  "license": "MIT",
14
15
  "devDependencies": {
16
+ "@playwright/test": "^1.40.1",
17
+ "@types/jest": "^29.5.12",
15
18
  "@types/node": "^20.10.5",
16
19
  "dotenv-webpack": "^8.0.0",
20
+ "ts-loader": "^9.5.1",
17
21
  "typescript": "^4.7.4",
18
22
  "webpack": "^5.73.0",
19
23
  "webpack-cli": "^4.10.0",
20
- "webpack-dev-server": "^4.11.1",
21
- "@playwright/test": "^1.40.1"
24
+ "webpack-dev-server": "^4.11.1"
22
25
  }
23
26
  }
@@ -29,7 +29,7 @@ export default defineConfig({
29
29
  /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
30
30
  trace: "on-first-retry",
31
31
  },
32
-
32
+ timeout: 5 * 1000,
33
33
  /* Configure projects for major browsers */
34
34
  projects: [
35
35
  {
@@ -35,7 +35,7 @@
35
35
  aria-label="A leaflet map used for testing purposes">
36
36
  </div>
37
37
  </div>
38
- <div class="buttons">
38
+ <div class="buttons" data-testid="buttons">
39
39
  <button id="select">Select</button>
40
40
  <button id="point">Point</button>
41
41
  <button id="linestring">Linestring</button>
package/e2e/src/index.ts CHANGED
@@ -46,6 +46,7 @@ const example = {
46
46
  }),
47
47
  modes: [
48
48
  new TerraDrawSelectMode({
49
+ dragEventThrottle: 0,
49
50
  flags: {
50
51
  arbitary: {
51
52
  feature: {},
@@ -1,6 +1,8 @@
1
1
  import { test, expect } from "@playwright/test";
2
2
  import {
3
3
  changeMode,
4
+ drawRectanglePolygon,
5
+ expectGroupPosition,
4
6
  expectPathDimensions,
5
7
  expectPaths,
6
8
  pageUrl,
@@ -24,6 +26,26 @@ test.describe("page setup", () => {
24
26
  await expect(page.getByText("Select")).toBeVisible();
25
27
  await expect(page.getByText("Clear")).toBeVisible();
26
28
  });
29
+
30
+ test("there are no console errors", async ({ page }) => {
31
+ const errors: string[] = [];
32
+ page.on("console", (msg) => {
33
+ if (msg.type() === "error") {
34
+ errors.push(msg.text());
35
+ }
36
+ });
37
+ await page.goto(pageUrl);
38
+ await expect(page.getByRole("application")).toBeVisible();
39
+
40
+ expect(errors).toEqual([]);
41
+ });
42
+
43
+ test("there are no build issues", async ({ page }) => {
44
+ await page.goto(pageUrl);
45
+ await expect(
46
+ await page.locator("#webpack-dev-server-client-overlay").count(),
47
+ ).toBe(0);
48
+ });
27
49
  });
28
50
 
29
51
  test.describe("point mode", () => {
@@ -32,10 +54,9 @@ test.describe("point mode", () => {
32
54
  test("mode can set and can be used to create a point", async ({ page }) => {
33
55
  const mapDiv = await setupMap({ page });
34
56
  await changeMode({ page, mode });
35
-
36
57
  await page.mouse.click(mapDiv.width / 2, mapDiv.height / 2);
37
58
 
38
- expectPaths({ page, count: 1 });
59
+ await expectPaths({ page, count: 1 });
39
60
  });
40
61
 
41
62
  test("mode can set and can be used to create multiple points", async ({
@@ -48,7 +69,7 @@ test.describe("point mode", () => {
48
69
  await page.mouse.click(mapDiv.width / 3, mapDiv.height / 3);
49
70
  await page.mouse.click(mapDiv.width / 2, mapDiv.height / 2);
50
71
 
51
- expectPaths({ page, count: 3 });
72
+ await expectPaths({ page, count: 3 });
52
73
  });
53
74
  });
54
75
 
@@ -68,7 +89,7 @@ test.describe("linestring mode", () => {
68
89
 
69
90
  await page.mouse.click(mapDiv.width / 3, mapDiv.height / 3);
70
91
 
71
- expectPaths({ page, count: 1 });
92
+ await expectPaths({ page, count: 1 });
72
93
  });
73
94
 
74
95
  test("mode can set and can be used to create multiple linestrings", async ({
@@ -84,13 +105,13 @@ test.describe("linestring mode", () => {
84
105
  await page.mouse.click(mapDiv.width / 3, mapDiv.height / 3);
85
106
 
86
107
  // One point + one line
87
- expectPaths({ page, count: 2 });
108
+ await expectPaths({ page, count: 2 });
88
109
 
89
110
  // Close first line
90
111
  await page.mouse.click(mapDiv.width / 3, mapDiv.height / 3);
91
112
 
92
113
  // One line
93
- expectPaths({ page, count: 2 });
114
+ await expectPaths({ page, count: 1 });
94
115
 
95
116
  // Second line
96
117
  await page.mouse.move(mapDiv.width / 4, mapDiv.height / 4);
@@ -102,7 +123,7 @@ test.describe("linestring mode", () => {
102
123
  await page.mouse.click(mapDiv.width / 5, mapDiv.height / 5);
103
124
 
104
125
  // Two lines
105
- expectPaths({ page, count: 2 });
126
+ await expectPaths({ page, count: 2 });
106
127
  });
107
128
  });
108
129
 
@@ -139,7 +160,7 @@ test.describe("polygon mode", () => {
139
160
  await page.mouse.click(bottomLeft.x, bottomLeft.y);
140
161
 
141
162
  // One point + one line
142
- expectPaths({ page, count: 1 });
163
+ await expectPaths({ page, count: 1 });
143
164
  });
144
165
  });
145
166
 
@@ -229,6 +250,74 @@ test.describe("select mode", () => {
229
250
  await page.mouse.click(mapDiv.width - 10, mapDiv.height / 2);
230
251
  await expectPaths({ page, count: 1 }); // 0 selection points and 1 square
231
252
  });
253
+
254
+ test("selected polygon can be dragged", async ({ page }) => {
255
+ const mapDiv = await setupMap({ page });
256
+
257
+ await changeMode({ page, mode: "polygon" });
258
+
259
+ // Draw a rectangle
260
+ const { topLeft } = await drawRectanglePolygon({ mapDiv, page });
261
+
262
+ // Change to select mode
263
+ await changeMode({ page, mode });
264
+
265
+ // Before drag
266
+ const x = topLeft.x - 2;
267
+ const y = topLeft.y - 2;
268
+ await expectGroupPosition({ page, x, y });
269
+
270
+ // Select
271
+ await page.mouse.click(mapDiv.width / 2, mapDiv.height / 2);
272
+ await expectPaths({ page, count: 9 }); // 8 selection points and 1 square
273
+
274
+ // Drag
275
+ await page.mouse.move(mapDiv.width / 2, mapDiv.height / 2);
276
+ await page.mouse.down();
277
+ await page.mouse.move(mapDiv.width / 2 + 50, mapDiv.height / 2 + 50, {
278
+ steps: 30,
279
+ }); // Steps is required
280
+ await page.mouse.up();
281
+
282
+ await page.mouse.click(mapDiv.width - 10, mapDiv.height / 2);
283
+
284
+ await expectGroupPosition({ page, x: x + 48, y: y + 48 });
285
+ });
286
+
287
+ test("selected polygon can have individual coordinates dragged", async ({
288
+ page,
289
+ }) => {
290
+ const mapDiv = await setupMap({ page });
291
+
292
+ await changeMode({ page, mode: "polygon" });
293
+
294
+ // Draw a rectangle
295
+ const { topLeft } = await drawRectanglePolygon({ mapDiv, page });
296
+
297
+ // Change to select mode
298
+ await changeMode({ page, mode });
299
+
300
+ // Before drag
301
+ const x = topLeft.x - 2;
302
+ const y = topLeft.y - 2;
303
+ await expectGroupPosition({ page, x, y });
304
+
305
+ // Select
306
+ await page.mouse.click(mapDiv.width / 2, mapDiv.height / 2);
307
+ await expectPaths({ page, count: 9 }); // 8 selection points and 1 square
308
+
309
+ // Drag
310
+ await page.mouse.move(topLeft.x, topLeft.y);
311
+ await page.mouse.down();
312
+ await page.mouse.move(topLeft.x - 50, topLeft.y + 50, { steps: 30 }); // Steps is required
313
+ await page.mouse.up();
314
+
315
+ // Deselect
316
+ await page.mouse.click(mapDiv.width - 10, mapDiv.height / 2);
317
+
318
+ // Dragged the coordinate to the left and down slightly
319
+ await expectGroupPosition({ page, x: 538, y: 308 });
320
+ });
232
321
  });
233
322
 
234
323
  test.describe("clear", () => {
@@ -244,25 +333,13 @@ test.describe("clear", () => {
244
333
  await page.mouse.click(mapDiv.width / 3, mapDiv.height / 3);
245
334
 
246
335
  await changeMode({ page, mode: "polygon" });
247
- const sideLength = 100;
248
- const halfLength = sideLength / 2;
249
- const centerX = mapDiv.width / 2;
250
- const centerY = mapDiv.height / 2;
251
- const topLeft = { x: centerX - halfLength, y: centerY - halfLength };
252
- const topRight = { x: centerX + halfLength, y: centerY - halfLength };
253
- const bottomLeft = { x: centerX - halfLength, y: centerY + halfLength };
254
- const bottomRight = { x: centerX + halfLength, y: centerY + halfLength };
255
- await page.mouse.click(topLeft.x, topLeft.y);
256
- await page.mouse.click(topRight.x, topRight.y);
257
- await page.mouse.click(bottomRight.x, bottomRight.y);
258
- await page.mouse.click(bottomLeft.x, bottomLeft.y);
259
- await page.mouse.click(bottomLeft.x, bottomLeft.y); // Closed
336
+ await drawRectanglePolygon({ mapDiv, page });
260
337
 
261
- expectPaths({ page, count: 3 });
338
+ await expectPaths({ page, count: 3 });
262
339
 
263
340
  const button = page.getByText("clear");
264
341
  await button.click();
265
342
 
266
- expectPaths({ page, count: 0 });
343
+ await expectPaths({ page, count: 0 });
267
344
  });
268
345
  });
@@ -41,7 +41,8 @@ export const changeMode = async ({
41
41
  | "greatcircle";
42
42
  }) => {
43
43
  const modeText = mode.charAt(0).toUpperCase() + mode.slice(1);
44
- const button = page.getByText(modeText);
44
+ const buttons = page.getByTestId("buttons");
45
+ const button = buttons.getByText(modeText, { exact: true });
45
46
 
46
47
  // Click the mode button
47
48
  await button.click();
@@ -63,7 +64,7 @@ export const expectPaths = async ({
63
64
  const selector = "svg > g > path";
64
65
 
65
66
  if (count > 0) {
66
- page.waitForSelector(selector);
67
+ await page.waitForSelector(selector);
67
68
  expect(await page.locator(selector).count()).toBe(count);
68
69
  } else {
69
70
  await expect(await page.locator(selector).count()).toBe(0);
@@ -86,3 +87,50 @@ export const expectPathDimensions = async ({
86
87
  expect(boundingBox?.width).toBe(width);
87
88
  expect(boundingBox?.height).toBe(height);
88
89
  };
90
+
91
+ export const expectGroupPosition = async ({
92
+ page,
93
+ x,
94
+ y,
95
+ }: {
96
+ page: Page;
97
+ x: number;
98
+ y: number;
99
+ }) => {
100
+ const selector = "svg > g > path";
101
+
102
+ const boundingBox = await page.locator(selector).boundingBox();
103
+
104
+ expect(boundingBox?.x).toBe(x);
105
+ expect(boundingBox?.y).toBe(y);
106
+ };
107
+
108
+ export const drawRectanglePolygon = async ({
109
+ mapDiv,
110
+ page,
111
+ }: {
112
+ mapDiv: {
113
+ x: number;
114
+ y: number;
115
+ width: number;
116
+ height: number;
117
+ };
118
+ page: Page;
119
+ }) => {
120
+ // Draw a rectangle
121
+ const sideLength = 100;
122
+ const halfLength = sideLength / 2;
123
+ const centerX = mapDiv.width / 2;
124
+ const centerY = mapDiv.height / 2;
125
+ const topLeft = { x: centerX - halfLength, y: centerY - halfLength };
126
+ const topRight = { x: centerX + halfLength, y: centerY - halfLength };
127
+ const bottomLeft = { x: centerX - halfLength, y: centerY + halfLength };
128
+ const bottomRight = { x: centerX + halfLength, y: centerY + halfLength };
129
+ await page.mouse.click(topLeft.x, topLeft.y);
130
+ await page.mouse.click(topRight.x, topRight.y);
131
+ await page.mouse.click(bottomRight.x, bottomRight.y);
132
+ await page.mouse.click(bottomLeft.x, bottomLeft.y);
133
+ await page.mouse.click(bottomLeft.x, bottomLeft.y); // Closed
134
+
135
+ return { topLeft, topRight, bottomRight, bottomLeft };
136
+ };
@@ -26,12 +26,10 @@ module.exports = {
26
26
  static: {
27
27
  directory: path.join(__dirname, "public"),
28
28
  },
29
- watchFiles: [
30
- "./src",
31
- "./*.{js,json,ts,html}",
32
- "../src",
33
- "../*.{js,json,ts,html}",
34
- ],
29
+ liveReload: !process.env.CI,
30
+ watchFiles: !process.env.CI
31
+ ? ["./src", "./*.{js,json,ts,html}", "../src", "../*.{js,json,ts,html}"]
32
+ : [],
35
33
  compress: true,
36
34
  port: 3000,
37
35
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "terra-draw",
3
- "version": "0.0.1-alpha.54",
3
+ "version": "0.0.1-alpha.56",
4
4
  "description": "Frictionless map drawing across mapping provider",
5
5
  "scripts": {
6
6
  "docs": "typedoc",