Replace WebDriverIO with Cypress (#831)

This does the following:
1. Moves the WDIO code from javascript to typescript
2. Moves to use files that are `cy.ts` instead of `index.js`
3. Replace e2e to use cypress
4. Introduce back some skipped tests

This is in continue to the conversation here:
https://github.com/HarelM/editor/pull/3

Before:
```
 "spec" Reporter:
------------------------------------------------------------------
[chrome 120.0.6099.71 linux #0-0] Running: chrome (v120.0.6099.71) on linux
[chrome 120.0.6099.71 linux #0-0] Session ID: ee9a87bcfce007ac7721929c6e6234d0
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0] » /test/functional/index.js
[chrome 120.0.6099.71 linux #0-0] maputnik
[chrome 120.0.6099.71 linux #0-0]     history
[chrome 120.0.6099.71 linux #0-0]        - undo/redo
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]     layers
[chrome 120.0.6099.71 linux #0-0]         ops
[chrome 120.0.6099.71 linux #0-0]            ✓ delete
[chrome 120.0.6099.71 linux #0-0]            ✓ duplicate
[chrome 120.0.6099.71 linux #0-0]            ✓ hide
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         background
[chrome 120.0.6099.71 linux #0-0]            ✓ add
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]             modify
[chrome 120.0.6099.71 linux #0-0]                 layer
[chrome 120.0.6099.71 linux #0-0]                    - expand/collapse
[chrome 120.0.6099.71 linux #0-0]                    ✓ id
[chrome 120.0.6099.71 linux #0-0]                    ✓ min-zoom
[chrome 120.0.6099.71 linux #0-0]                    ✓ max-zoom
[chrome 120.0.6099.71 linux #0-0]                    ✓ comments
[chrome 120.0.6099.71 linux #0-0]                    - color
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]                 filter
[chrome 120.0.6099.71 linux #0-0]                    - expand/collapse
[chrome 120.0.6099.71 linux #0-0]                    - compound filter
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]                 paint
[chrome 120.0.6099.71 linux #0-0]                    - expand/collapse
[chrome 120.0.6099.71 linux #0-0]                    - color
[chrome 120.0.6099.71 linux #0-0]                    - pattern
[chrome 120.0.6099.71 linux #0-0]                    - opacity
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]                 json-editor
[chrome 120.0.6099.71 linux #0-0]                    - expand/collapse
[chrome 120.0.6099.71 linux #0-0]                    - modify
[chrome 120.0.6099.71 linux #0-0]                    - parse error
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         fill
[chrome 120.0.6099.71 linux #0-0]            ✓ add
[chrome 120.0.6099.71 linux #0-0]            - change source
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         line
[chrome 120.0.6099.71 linux #0-0]            ✓ add
[chrome 120.0.6099.71 linux #0-0]            - groups
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         symbol
[chrome 120.0.6099.71 linux #0-0]            ✓ add
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         raster
[chrome 120.0.6099.71 linux #0-0]            ✓ add
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         circle
[chrome 120.0.6099.71 linux #0-0]            ✓ add
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         fill extrusion
[chrome 120.0.6099.71 linux #0-0]            ✓ add
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         groups
[chrome 120.0.6099.71 linux #0-0]            ✓ simple
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]     map
[chrome 120.0.6099.71 linux #0-0]         zoom level
[chrome 120.0.6099.71 linux #0-0]            - via url
[chrome 120.0.6099.71 linux #0-0]            - via map controls
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]     modals
[chrome 120.0.6099.71 linux #0-0]         open
[chrome 120.0.6099.71 linux #0-0]            ✓ close
[chrome 120.0.6099.71 linux #0-0]            - upload
[chrome 120.0.6099.71 linux #0-0]            ✓ load from url
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         shortcuts
[chrome 120.0.6099.71 linux #0-0]            ✓ open/close
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         export
[chrome 120.0.6099.71 linux #0-0]            ✓ close
[chrome 120.0.6099.71 linux #0-0]            - download
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         sources
[chrome 120.0.6099.71 linux #0-0]            - active sources
[chrome 120.0.6099.71 linux #0-0]            - public source
[chrome 120.0.6099.71 linux #0-0]            - add new source
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         inspect
[chrome 120.0.6099.71 linux #0-0]            ✓ toggle
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         style settings
[chrome 120.0.6099.71 linux #0-0]            ✓ name
[chrome 120.0.6099.71 linux #0-0]            ✓ owner
[chrome 120.0.6099.71 linux #0-0]            ✓ sprite url
[chrome 120.0.6099.71 linux #0-0]            ✓ glyphs url
[chrome 120.0.6099.71 linux #0-0]            ✓ maptiler access token
[chrome 120.0.6099.71 linux #0-0]            ✓ thunderforest access token
[chrome 120.0.6099.71 linux #0-0]            ✓ style renderer
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]         sources
[chrome 120.0.6099.71 linux #0-0]            - toggle
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]     screenshots
[chrome 120.0.6099.71 linux #0-0]        ✓ front_page
[chrome 120.0.6099.71 linux #0-0]        ✓ open
[chrome 120.0.6099.71 linux #0-0]        ✓ export
[chrome 120.0.6099.71 linux #0-0]        ✓ sources
[chrome 120.0.6099.71 linux #0-0]        ✓ style settings
[chrome 120.0.6099.71 linux #0-0]        ✓ inspect
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]     accessibility
[chrome 120.0.6099.71 linux #0-0]         skip links
[chrome 120.0.6099.71 linux #0-0]            ✓ skip link to layer list
[chrome 120.0.6099.71 linux #0-0]            ✓ skip link to layer editor
[chrome 120.0.6099.71 linux #0-0]            ✓ skip link to map view
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0]     keyboard
[chrome 120.0.6099.71 linux #0-0]         shortcuts
[chrome 120.0.6099.71 linux #0-0]            ✓ ESC should unfocus
[chrome 120.0.6099.71 linux #0-0]            ✓ '?' should show shortcuts modal
[chrome 120.0.6099.71 linux #0-0]            ✓ 'o' should show open modal
[chrome 120.0.6099.71 linux #0-0]            ✓ 'e' should show export modal
[chrome 120.0.6099.71 linux #0-0]            ✓ 'd' should show sources modal
[chrome 120.0.6099.71 linux #0-0]            ✓ 's' should show settings modal
[chrome 120.0.6099.71 linux #0-0]            - 'i' should change map to inspect mode
[chrome 120.0.6099.71 linux #0-0]            ✓ 'm' should focus map
[chrome 120.0.6099.71 linux #0-0]            ✓ '!' should show debug modal
[chrome 120.0.6099.71 linux #0-0]
[chrome 120.0.6099.71 linux #0-0] 44 passing (58.8s)
[chrome 120.0.6099.71 linux #0-0] 23 skipped
```

After:
```
accessibility
    skip links
      - skip link to layer list
      - skip link to layer editor
      - skip link to map view

history
    ✓ undo/redo (4894ms)

keyboard
    shortcuts
      ✓ ESC should unfocus (1912ms)
      ✓ '?' should show shortcuts modal (458ms)
      ✓ 'o' should show open modal (710ms)
      ✓ 'e' should show export modal (692ms)
      ✓ 'd' should show sources modal (588ms)
      ✓ 's' should show settings modal (894ms)
      ✓ 'i' should change map to inspect mode (804ms)
      ✓ 'm' should focus map (837ms)
      ✓ '!' should show debug modal (607ms)

layers
    ops
      ✓ delete (4313ms)
      ✓ duplicate (1780ms)
      ✓ hide (1862ms)
    background
      ✓ add (1675ms)
      modify
        layer
          - expand/collapse
          ✓ id (3735ms)
          ✓ min-zoom (2209ms)
          ✓ max-zoom (2127ms)
          ✓ comments (2515ms)
          ✓ color (2022ms)
        filter
          - expand/collapse
          - compound filter
        paint
          - expand/collapse
          - color
          - pattern
          - opacity
        json-editor
          - expand/collapse
          - modify
          - parse error
    fill
      ✓ add (1831ms)
      - change source
    line
      ✓ add (1844ms)
      ✓ groups (687ms)
    symbol
      ✓ add (2035ms)
    raster
      ✓ add (1814ms)
    circle
      ✓ add (1867ms)
    fill extrusion
      ✓ add (1963ms)
    groups
      ✓ simple (2653ms)

map
    zoom level
      ✓ via url (2279ms)
      ✓ via map controls (733ms)

modals
    open
      ✓ close (2519ms)
      - upload
      ✓ load from url (1557ms)
    shortcuts
      ✓ open/close (1136ms)
    export
      ✓ close (755ms)
      - download
    sources
      - active sources
      - public source
      - add new source
    inspect
      ✓ toggle (1020ms)
    style settings
      ✓ name (1085ms)
      ✓ owner (1060ms)
      ✓ sprite url (1214ms)
      ✓ glyphs url (1553ms)
      ✓ maptiler access token (1111ms)
      ✓ thunderforest access token (1102ms)
      ✓ style renderer (922ms)
    sources
      - toggle



      Spec                                              Tests  Passing  Failing  Pending  Skipped  
  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ ✔  accessibility.cy.ts                       52ms        3        -        -        3        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  history.cy.ts                            00:06        1        1        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  keyboard.cy.ts                           00:10        9        9        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  layers.cy.ts                             00:39       28       17        -       11        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  map.cy.ts                                00:04        2        2        -        -        - │
  ├────────────────────────────────────────────────────────────────────────────────────────────────┤
  │ ✔  modals.cy.ts                             00:16       18       12        -        6        - │
  └────────────────────────────────────────────────────────────────────────────────────────────────┘
    ✔  All specs passed!                        01:18       61       41        -       20        -  
```

---------

Co-authored-by: Yuri Astrakhan <yuriastrakhan@gmail.com>
This commit is contained in:
Harel M
2023-12-17 21:49:23 +02:00
committed by GitHub
parent 0c46affda9
commit 1df2e36dbb
40 changed files with 2953 additions and 8099 deletions

View File

@@ -0,0 +1,41 @@
import driver from "./driver";
describe("accessibility", () => {
// skipped due to the following issue with cypress: https://github.com/cypress-io/cypress/issues/299
describe.skip("skip links", () => {
beforeEach(() => {
driver.beforeEach();
driver.setStyle("layer");
});
it("skip link to layer list", () => {
const selector = driver.getDataAttribute("root:skip:layer-list");
driver.isExists(selector);
driver.typeKeys('{tab}');
driver.isFocused(selector);
driver.click(selector);
driver.isFocused("#skip-target-layer-list");
});
it("skip link to layer editor", () => {
const selector = driver.getDataAttribute("root:skip:layer-editor");
driver.isExists(selector);
driver.typeKeys('{tab}{tab}');
driver.isFocused(selector);
driver.click(selector);
driver.isFocused("#skip-target-layer-editor");
});
it("skip link to map view", () => {
const selector = driver.getDataAttribute("root:skip:map-view");
driver.isExists(selector);
driver.typeKeys('{tab}{tab}{tab}');
driver.isFocused(selector);
driver.click(selector);
driver.isFocused(".maplibregl-canvas");
});
});
})

170
cypress/e2e/driver.ts Normal file
View File

@@ -0,0 +1,170 @@
import {v1 as uuid} from "uuid";
export default {
isMac() {
return Cypress.platform === "darwin";
},
beforeEach() {
this.setupInterception();
this.setStyle('both');
},
setupInterception() {
cy.intercept('GET', 'http://localhost:8888/example-style.json', { fixture: 'example-style.json' }).as('example-style.json');
cy.intercept('GET', 'http://localhost:8888/example-layer-style.json', { fixture: 'example-layer-style.json' });
cy.intercept('GET', 'http://localhost:8888/geojson-style.json', { fixture: 'geojson-style.json' });
cy.intercept('GET', 'http://localhost:8888/raster-style.json', { fixture: 'raster-style.json' });
cy.intercept('GET', 'http://localhost:8888/geojson-raster-style.json', { fixture: 'geojson-raster-style.json' });
cy.intercept({method: 'GET', url: '*example.local/*' }, []);
cy.intercept({method: 'GET', url: '*example.com/*' }, []);
},
setStyle(styleProperties: 'geojson' | 'raster' | 'both' | 'layer' | '', zoom? : number) {
let url = "?debug";
switch (styleProperties) {
case "geojson":
url += "&style=http://localhost:8888/geojson-style.json";
break;
case "raster":
url += "&style=http://localhost:8888/raster-style.json";
break;
case "both":
url += "&style=http://localhost:8888/geojson-raster-style.json";
break;
case "layer":
url += "&style=http://localhost:8888/example-layer-style.json";
break;
}
if (zoom) {
url += "#" + zoom + "/41.3805/2.1635";
}
cy.visit("http://localhost:8888/" + url);
if (styleProperties) {
cy.on('window:confirm', () => true)
}
cy.get(".maputnik-toolbar-link").should("be.visible");
},
getDataAttribute(key: string, selector?: string) {
return `*[data-wd-key='${key}'] ${selector || ''}`;
},
closeModal(key: string) {
const selector = this.getDataAttribute(key);
this.isDisplayedInViewport(selector);
this.click(this.getDataAttribute(key + ".close-modal"));
this.doesNotExists(selector);
},
openLayersModal() {
cy.get(this.getDataAttribute('layer-list:add-layer')).click();
cy.get(this.getDataAttribute('modal:add-layer')).should('exist');
cy.get(this.getDataAttribute('modal:add-layer')).should('be.visible');
},
getStyleFromWindow(win: Window) {
const styleId = win.localStorage.getItem("maputnik:latest_style");
const styleItem = win.localStorage.getItem(`maputnik:style:${styleId}`)
const obj = JSON.parse(styleItem || "");
return obj;
},
isStyleStoreEqual(getter: (obj:any) => any, styleObj: any) {
cy.window().then((win: any) => {
const obj = this.getStyleFromWindow(win);
assert.deepEqual(getter(obj), styleObj);
});
},
isStyleStoreEqualToExampleFileData() {
cy.window().then((win: any) => {
const obj = this.getStyleFromWindow(win);
cy.fixture('example-style.json').should('deep.equal', obj);
});
},
fillLayersModal(opts: any) {
var type = opts.type;
var layer = opts.layer;
var id;
if(opts.id) {
id = opts.id
}
else {
id = `${type}:${uuid()}`;
}
cy.get(this.getDataAttribute('add-layer.layer-type', "select")).select(type);
cy.get(this.getDataAttribute("add-layer.layer-id", "input")).type(id);
if(layer) {
cy.get(this.getDataAttribute("add-layer.layer-source-block", "input")).type(layer);
}
cy.get(this.getDataAttribute("add-layer")).click();
return id;
},
typeKeys(keys: string) {
cy.get('body').type(keys);
},
click(selector: string) {
cy.get(selector).click();
},
select(selector: string, value: string) {
cy.get(selector).select(value);
},
isSelected(selector: string, value: string) {
cy.get(selector).find(`option[value="${value}"]`).should("be.selected");
},
focus(selector: string) {
cy.get(selector).focus();
},
isFocused(selector: string) {
cy.get(selector).should('have.focus');
},
isDisplayedInViewport(selector: string) {
cy.get(selector).should('be.visible');
},
isNotDisplayedInViewport(selector: string) {
cy.get(selector).should('not.be.visible');
},
setValue(selector: string, text: string) {
cy.get(selector).clear().type(text, {parseSpecialCharSequences: false});
},
isExists(selector: string) {
cy.get(selector).should('exist');
},
doesNotExists(selector: string) {
cy.get(selector).should('not.exist');
},
chooseExampleFile() {
cy.get("input[type='file']").selectFile('cypress/fixtures/example-style.json', {force: true});
},
getExampleFileUrl() {
return "http://localhost:8888/example-style.json";
},
waitForExampleFileRequset() {
cy.wait('@example-style.json');
}
}

80
cypress/e2e/history.cy.ts Normal file
View File

@@ -0,0 +1,80 @@
import driver from "./driver";
describe("history", () => {
let undoKeyCombo: string;
let redoKeyCombo: string;
before(() => {
const isMac = driver.isMac();
undoKeyCombo = isMac ? '{meta}z' : '{ctrl}z';
redoKeyCombo = isMac ? '{meta}{shift}z' : '{ctrl}y';
driver.beforeEach();
});
it("undo/redo", () => {
driver.setStyle('geojson');
driver.openLayersModal();
driver.isStyleStoreEqual((a: any) => a.layers, []);
driver.fillLayersModal({
id: "step 1",
type: "background"
})
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": "step 1",
"type": 'background'
}
]);
driver.openLayersModal();
driver.fillLayersModal({
id: "step 2",
type: "background"
})
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": "step 1",
"type": 'background'
},
{
"id": "step 2",
"type": 'background'
}
]);
driver.typeKeys(undoKeyCombo);
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": "step 1",
"type": 'background'
}
]);
driver.typeKeys(undoKeyCombo)
driver.isStyleStoreEqual((a: any) => a.layers, []);
driver.typeKeys(redoKeyCombo)
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": "step 1",
"type": 'background'
}
]);
driver.typeKeys(redoKeyCombo)
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": "step 1",
"type": 'background'
},
{
"id": "step 2",
"type": 'background'
}
]);
});
})

View File

@@ -0,0 +1,60 @@
import driver from "./driver";
describe("keyboard", () => {
describe("shortcuts", () => {
beforeEach(() => {
driver.setupInterception();
driver.setStyle('');
})
it("ESC should unfocus", () => {
const targetSelector = driver.getDataAttribute("nav:inspect") + " select";
driver.focus(targetSelector);
driver.isFocused(targetSelector);
//driver.typeKeys("{esc}");
//driver.isFocused('body');
});
it("'?' should show shortcuts modal", () => {
driver.typeKeys("?");
driver.isDisplayedInViewport(driver.getDataAttribute("modal:shortcuts"));
});
it("'o' should show open modal", () => {
driver.typeKeys("o");
driver.isDisplayedInViewport(driver.getDataAttribute("modal:open"));
});
it("'e' should show export modal", () => {
driver.typeKeys("e");
driver.isDisplayedInViewport(driver.getDataAttribute("modal:export"));
});
it("'d' should show sources modal", () => {
driver.typeKeys("d");
driver.isDisplayedInViewport(driver.getDataAttribute("modal:sources"));
});
it("'s' should show settings modal", () => {
driver.typeKeys("s");
driver.isDisplayedInViewport(driver.getDataAttribute("modal:settings"));
});
it("'i' should change map to inspect mode", () => {
driver.typeKeys("i");
driver.isSelected(driver.getDataAttribute("nav:inspect"), "inspect");
});
it("'m' should focus map", () => {
driver.typeKeys("m");
driver.isFocused(".maplibregl-canvas");
});
it("'!' should show debug modal", () => {
driver.typeKeys("!");
driver.isDisplayedInViewport(driver.getDataAttribute("modal:debug"));
});
});
});

427
cypress/e2e/layers.cy.ts Normal file
View File

@@ -0,0 +1,427 @@
var assert = require("assert");
import driver from "./driver";
import { v1 as uuid } from 'uuid';
describe("layers", () => {
beforeEach(() => {
driver.beforeEach();
driver.setStyle('both');
driver.openLayersModal();
});
describe("ops", () => {
it("delete", () => {
var id = driver.fillLayersModal({
type: "background"
})
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": id,
"type": 'background'
},
]);
driver.click(driver.getDataAttribute("layer-list-item:"+id+":delete", ""))
driver.isStyleStoreEqual((a: any) => a.layers, []);
});
it("duplicate", () => {
var styleObj;
var id = driver.fillLayersModal({
type: "background"
})
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": id,
"type": 'background'
},
]);
driver.click(driver.getDataAttribute("layer-list-item:"+id+":copy", ""));
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": id+"-copy",
"type": "background"
},
{
"id": id,
"type": "background"
},
]);
});
it("hide", () => {
var styleObj;
var id = driver.fillLayersModal({
type: "background"
})
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": id,
"type": 'background'
},
]);
driver.click(driver.getDataAttribute("layer-list-item:"+id+":toggle-visibility", ""));
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": id,
"type": "background",
"layout": {
"visibility": "none"
}
},
]);
driver.click(driver.getDataAttribute("layer-list-item:"+id+":toggle-visibility", ""));
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": id,
"type": "background",
"layout": {
"visibility": "visible"
}
},
]);
})
})
describe('background', () => {
it("add", () => {
var id = driver.fillLayersModal({
type: "background"
})
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": id,
"type": 'background'
}
]);
});
describe("modify", () => {
function createBackground() {
// Setup
var id = uuid();
driver.select(driver.getDataAttribute("add-layer.layer-type", "select"), "background");
driver.setValue(driver.getDataAttribute("add-layer.layer-id", "input"), "background:"+id);
driver.click(driver.getDataAttribute("add-layer"));
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": 'background:'+id,
"type": 'background'
}
]);
return id;
}
// ====> THESE SHOULD BE FROM THE SPEC
describe("layer", () => {
it("expand/collapse");
it("id", () => {
var bgId = createBackground();
driver.click(driver.getDataAttribute("layer-list-item:background:"+bgId));
var id = uuid();
driver.setValue(driver.getDataAttribute("layer-editor.layer-id", "input"), "foobar:"+id)
driver.click(driver.getDataAttribute("min-zoom"));
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": 'foobar:'+id,
"type": 'background'
}
]);
});
it("min-zoom", () => {
var bgId = createBackground();
driver.click(driver.getDataAttribute("layer-list-item:background:"+bgId));
driver.setValue(driver.getDataAttribute("min-zoom", 'input[type="text"]'), "1");
driver.click(driver.getDataAttribute("layer-editor.layer-id", "input"));
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": 'background:'+bgId,
"type": 'background',
"minzoom": 1
}
]);
// AND RESET!
// driver.setValue(driver.getDataAttribute("min-zoom", "input"), "")
// driver.click(driver.getDataAttribute("max-zoom", "input"));
// driver.isStyleStoreEqual((a: any) => a.layers, [
// {
// "id": 'background:'+bgId,
// "type": 'background'
// }
// ]);
});
it("max-zoom", () => {
var bgId = createBackground();
driver.click(driver.getDataAttribute("layer-list-item:background:"+bgId));
driver.setValue(driver.getDataAttribute("max-zoom", 'input[type="text"]'), "1")
driver.click(driver.getDataAttribute("layer-editor.layer-id", "input"));
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": 'background:'+bgId,
"type": 'background',
"maxzoom": 1
}
]);
});
it("comments", () => {
var bgId = createBackground();
var id = uuid();
driver.click(driver.getDataAttribute("layer-list-item:background:"+bgId));
driver.setValue(driver.getDataAttribute("layer-comment", "textarea"), id);
driver.click(driver.getDataAttribute("layer-editor.layer-id", "input"));
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": 'background:'+bgId,
"type": 'background',
metadata: {
'maputnik:comment': id
}
}
]);
// Unset it again.
// TODO: This fails
// driver.setValue(driver.getDataAttribute("layer-comment", "textarea"), "");
// driver.click(driver.getDataAttribute("min-zoom", "input"));
// driver.isStyleStoreEqual((a: any) => a.layers, [
// {
// "id": 'background:'+bgId,
// "type": 'background'
// }
// ]);
});
it("color", () => {
var bgId = createBackground();
driver.click(driver.getDataAttribute("layer-list-item:background:"+bgId));
driver.click(driver.getDataAttribute("spec-field:background-color", "input"));
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": 'background:'+bgId,
"type": 'background'
}
]);
})
})
describe("filter", () => {
it("expand/collapse");
it("compound filter");
})
describe("paint", () => {
it("expand/collapse");
it("color");
it("pattern");
it("opacity");
})
// <=====
describe("json-editor", () => {
it("expand/collapse");
it("modify");
// TODO
it.skip("parse error", () => {
var bgId = createBackground();
driver.click(driver.getDataAttribute("layer-list-item:background:"+bgId));
var errorSelector = ".CodeMirror-lint-marker-error";
driver.doesNotExists(errorSelector);
driver.click(".CodeMirror");
driver.typeKeys("\uE013\uE013\uE013\uE013\uE013\uE013\uE013\uE013\uE013\uE013\uE013\uE013 {");
driver.isExists(errorSelector);
driver.click(driver.getDataAttribute("layer-editor.layer-id"));
});
});
})
});
describe('fill', () => {
it("add", () => {
var id = driver.fillLayersModal({
type: "fill",
layer: "example"
});
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": id,
"type": 'fill',
"source": "example"
}
]);
})
// TODO: Change source
it("change source")
});
describe('line', () => {
it("add", () => {
var id = driver.fillLayersModal({
type: "line",
layer: "example"
});
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": id,
"type": "line",
"source": "example",
}
]);
});
it("groups", () => {
// TODO
// Click each of the layer groups.
})
});
describe('symbol', () => {
it("add", () => {
var id = driver.fillLayersModal({
type: "symbol",
layer: "example"
});
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": id,
"type": "symbol",
"source": "example",
}
]);
});
});
describe('raster', () => {
it("add", () => {
var id = driver.fillLayersModal({
type: "raster",
layer: "raster"
});
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": id,
"type": "raster",
"source": "raster",
}
]);
});
});
describe('circle', () => {
it("add", () => {
var id = driver.fillLayersModal({
type: "circle",
layer: "example"
});
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": id,
"type": "circle",
"source": "example",
}
]);
});
});
describe('fill extrusion', () => {
it("add", () => {
var id = driver.fillLayersModal({
type: "fill-extrusion",
layer: "example"
});
driver.isStyleStoreEqual((a: any) => a.layers, [
{
"id": id,
"type": 'fill-extrusion',
"source": "example"
}
]);
});
});
describe("groups", () => {
it("simple", () => {
driver.setStyle("geojson");
driver.openLayersModal();
driver.fillLayersModal({
id: "foo",
type: "background"
})
driver.openLayersModal();
driver.fillLayersModal({
id: "foo_bar",
type: "background"
})
driver.openLayersModal();
driver.fillLayersModal({
id: "foo_bar_baz",
type: "background"
})
driver.isDisplayedInViewport(driver.getDataAttribute("layer-list-item:foo"));
driver.isNotDisplayedInViewport(driver.getDataAttribute("layer-list-item:foo_bar"));
driver.isNotDisplayedInViewport(driver.getDataAttribute("layer-list-item:foo_bar_baz"));
driver.click(driver.getDataAttribute("layer-list-group:foo-0"));
driver.isDisplayedInViewport(driver.getDataAttribute("layer-list-item:foo"));
driver.isDisplayedInViewport(driver.getDataAttribute("layer-list-item:foo_bar"));
driver.isDisplayedInViewport(driver.getDataAttribute("layer-list-item:foo_bar_baz"));
})
})
});

25
cypress/e2e/map.cy.ts Normal file
View File

@@ -0,0 +1,25 @@
import driver from "./driver";
describe("map", () => {
describe("zoom level", () => {
beforeEach(() => {
driver.beforeEach();
});
it("via url", () => {
var zoomLevel = 12.37;
driver.setStyle("geojson", zoomLevel);
driver.isDisplayedInViewport(".maplibregl-ctrl-zoom");
// HM TODO
//driver.getText(".maplibregl-ctrl-zoom") === "Zoom "+(zoomLevel);
})
it("via map controls", () => {
var zoomLevel = 12.37;
driver.setStyle("geojson", zoomLevel);
driver.click(".maplibregl-ctrl-zoom-in");
driver.isDisplayedInViewport(".maplibregl-ctrl-zoom");
// HM TODO
//driver.getText(".maplibregl-ctrl-zoom") === "Zoom "+(zoomLevel + 1);
})
})
})

137
cypress/e2e/modals.cy.ts Normal file
View File

@@ -0,0 +1,137 @@
import driver from "./driver";
describe("modals", () => {
beforeEach(() => {
driver.beforeEach();
driver.setStyle('');
});
describe("open", () => {
beforeEach(() => {
driver.click(driver.getDataAttribute("nav:open"));
});
it("close", () => {
driver.closeModal("modal:open");
});
it.skip("upload", () => {
// HM: I was not able to make the following choose file actually to select a file and close the modal...
driver.chooseExampleFile();
driver.isStyleStoreEqualToExampleFileData();
});
it("load from url", () => {
var styleFileUrl = driver.getExampleFileUrl();
driver.setValue(driver.getDataAttribute("modal:open.url.input"), styleFileUrl);
driver.click(driver.getDataAttribute("modal:open.url.button"))
driver.waitForExampleFileRequset();
driver.isStyleStoreEqualToExampleFileData();
});
})
describe("shortcuts", () => {
it("open/close", () => {
driver.setStyle('');
driver.typeKeys("?");
driver.isDisplayedInViewport(driver.getDataAttribute("modal:shortcuts"));
driver.closeModal("modal:shortcuts");
});
});
describe("export", () => {
beforeEach(() => {
driver.click(driver.getDataAttribute("nav:export"));
});
it("close", () => {
driver.closeModal("modal:export");
});
// TODO: Work out how to download a file and check the contents
it("download")
})
describe("sources", () => {
it("active sources")
it("public source")
it("add new source")
})
describe("inspect", () => {
it("toggle", () => {
driver.setStyle('geojson');
driver.select(driver.getDataAttribute("nav:inspect", "select"), "inspect");
})
})
describe("style settings", () => {
beforeEach(() => {
driver.click(driver.getDataAttribute("nav:settings"));
});
it("name", () => {
driver.setValue(driver.getDataAttribute("modal:settings.name"), "foobar");
driver.click(driver.getDataAttribute("modal:settings.owner"));
driver.isStyleStoreEqual((obj) => obj.name, "foobar");
})
it("owner", () => {
driver.setValue(driver.getDataAttribute("modal:settings.owner"), "foobar")
driver.click(driver.getDataAttribute("modal:settings.name"));
driver.isStyleStoreEqual((obj) => obj.owner, "foobar");
})
it("sprite url", () => {
driver.setValue(driver.getDataAttribute("modal:settings.sprite"), "http://example.com")
driver.click(driver.getDataAttribute("modal:settings.name"));
driver.isStyleStoreEqual((obj) => obj.sprite, "http://example.com");
})
it("glyphs url", () => {
var glyphsUrl = "http://example.com/{fontstack}/{range}.pbf"
driver.setValue(driver.getDataAttribute("modal:settings.glyphs"), glyphsUrl);
driver.click(driver.getDataAttribute("modal:settings.name"));
driver.isStyleStoreEqual((obj) => obj.glyphs, glyphsUrl);
})
it("maptiler access token", () => {
var apiKey = "testing123";
driver.setValue(driver.getDataAttribute("modal:settings.maputnik:openmaptiles_access_token"), apiKey);
driver.click(driver.getDataAttribute("modal:settings.name"));
driver.isStyleStoreEqual((obj) => obj.metadata["maputnik:openmaptiles_access_token"], apiKey);
})
it("thunderforest access token", () => {
var apiKey = "testing123";
driver.setValue(driver.getDataAttribute("modal:settings.maputnik:thunderforest_access_token"), apiKey);
driver.click(driver.getDataAttribute("modal:settings.name"));
driver.isStyleStoreEqual((obj) => obj.metadata["maputnik:thunderforest_access_token"], apiKey);
})
it("style renderer", () => {
cy.on('uncaught:exception', () => false); // this is due to the fact that this is an invalid style for openlayers
driver.select(driver.getDataAttribute("modal:settings.maputnik:renderer"), "ol");
driver.isSelected(driver.getDataAttribute("modal:settings.maputnik:renderer"), "ol");
driver.click(driver.getDataAttribute("modal:settings.name"));
driver.isStyleStoreEqual((obj) => obj.metadata["maputnik:renderer"], "ol");
})
})
describe("sources", () => {
it("toggle")
})
})

View File

@@ -0,0 +1,18 @@
{
"id": "test-style",
"version": 8,
"name": "Test Style",
"metadata": {
"maputnik:renderer": "mlgljs"
},
"sources": {},
"glyphs": "https://example.local/fonts/{fontstack}/{range}.pbf",
"sprites": "https://example.local/fonts/{fontstack}/{range}.pbf",
"layers": [
{
"id": "background",
"type": "background"
}
]
}

View File

@@ -0,0 +1,12 @@
{
"id": "test-style",
"version": 8,
"name": "Test Style",
"metadata": {
"maputnik:renderer": "mlgljs"
},
"sources": {},
"glyphs": "https://example.local/fonts/{fontstack}/{range}.pbf",
"sprites": "https://example.local/fonts/{fontstack}/{range}.pbf",
"layers": []
}

View File

@@ -0,0 +1,34 @@
{
"id": "test-style",
"version": 8,
"name": "Test Style",
"metadata": {
"maputnik:renderer": "mlgljs"
},
"sources": {
"example": {
"type": "vector",
"data": {
"type": "FeatureCollection",
"features":[{
"type": "Feature",
"properties": {
"name": "Dinagat Islands"
},
"geometry":{
"type": "Point",
"coordinates": [125.6, 10.1]
}
}]
}
},
"raster": {
"tileSize": 256,
"tiles": ["http://localhost/example/{x}/{y}/{z}"],
"type": "raster"
}
},
"glyphs": "https://example.local/fonts/{fontstack}/{range}.pbf",
"sprites": "https://example.local/fonts/{fontstack}/{range}.pbf",
"layers": []
}

View File

@@ -0,0 +1,29 @@
{
"id": "test-style",
"version": 8,
"name": "Test Style",
"metadata": {
"maputnik:renderer": "mlgljs"
},
"sources": {
"example": {
"type": "vector",
"data": {
"type": "FeatureCollection",
"features":[{
"type": "Feature",
"properties": {
"name": "Dinagat Islands"
},
"geometry":{
"type": "Point",
"coordinates": [125.6, 10.1]
}
}]
}
}
},
"glyphs": "https://example.local/fonts/{fontstack}/{range}.pbf",
"sprites": "https://example.local/fonts/{fontstack}/{range}.pbf",
"layers": []
}

View File

@@ -0,0 +1,18 @@
{
"id": "test-style",
"version": 8,
"name": "Test Style",
"metadata": {
"maputnik:renderer": "mlgljs"
},
"sources": {
"raster": {
"tileSize": 256,
"tiles": ["http://localhost/example/{x}/{y}/{z}"],
"type": "raster"
}
},
"glyphs": "https://example.local/fonts/{fontstack}/{range}.pbf",
"sprites": "https://example.local/fonts/{fontstack}/{range}.pbf",
"layers": []
}

View File

@@ -0,0 +1,37 @@
/// <reference types="cypress" />
// ***********************************************
// This example commands.ts shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
//
// declare global {
// namespace Cypress {
// interface Chainable {
// login(email: string, password: string): Chainable<void>
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
// }
// }
// }

20
cypress/support/e2e.ts Normal file
View File

@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/e2e.ts is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')