mirror of
https://github.com/maputnik/editor.git
synced 2026-09-01 18:07:37 +00:00
Compare commits
18 Commits
v2.0.0
...
a8a221ba15
| Author | SHA1 | Date | |
|---|---|---|---|
| a8a221ba15 | |||
| d6bf0a7a6c | |||
| 1df2e36dbb | |||
| 0c46affda9 | |||
| 18f45e932b | |||
| 31d56c9fae | |||
| b7838ad6e1 | |||
| c92fd12854 | |||
| eb55796461 | |||
| 4b97f82980 | |||
| 5d0b6e3201 | |||
| 5ab9be9fdb | |||
| 9659d41b83 | |||
| 52f949e152 | |||
| e4d559f953 | |||
| 577663f706 | |||
| 393f4a38b9 | |||
| 3727c9ad5e |
@@ -0,0 +1,14 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "npm"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
open-pull-requests-limit: 2
|
||||||
|
versioning-strategy: increase
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
open-pull-requests-limit: 2
|
||||||
|
versioning-strategy: increase
|
||||||
+18
-50
@@ -34,7 +34,7 @@ jobs:
|
|||||||
os: [ubuntu-latest]
|
os: [ubuntu-latest]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- run: docker build -t docker.pkg.github.com/maputnik/editor/editor:master .
|
- run: docker build -t docker.pkg.github.com/maputnik/editor/editor:master .
|
||||||
|
|
||||||
# build the editor
|
# build the editor
|
||||||
@@ -48,10 +48,10 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
node-version: [16.x]
|
node-version: [18.x]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
@@ -74,10 +74,10 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest]
|
os: [ubuntu-latest]
|
||||||
node-version: [16.x]
|
node-version: [18.x]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
@@ -115,7 +115,7 @@ jobs:
|
|||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Check out code into the Go module directory
|
- name: Check out code into the Go module directory
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
repository: maputnik/desktop
|
repository: maputnik/desktop
|
||||||
ref: master
|
ref: master
|
||||||
@@ -141,53 +141,21 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: maputnik-windows
|
name: maputnik-windows
|
||||||
path: ./src/github.com/maputnik/desktop/bin/windows/
|
path: ./src/github.com/maputnik/desktop/bin/windows/
|
||||||
|
|
||||||
# build and test the editor
|
cypress-run:
|
||||||
test_selenium_standalone:
|
|
||||||
name: "test/standalone-${{ matrix.browser }} (${{ matrix.os }})"
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
|
|
||||||
if: ${{ github.event_name == 'push' || github.event_name == 'pull_request' }}
|
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest]
|
|
||||||
node-version: [16]
|
|
||||||
browser: [chrome, firefox]
|
browser: [chrome, firefox]
|
||||||
|
|
||||||
container:
|
runs-on: ubuntu-22.04
|
||||||
image: node:${{ matrix.node-version }}
|
|
||||||
options: --network-alias testhost
|
|
||||||
|
|
||||||
services:
|
|
||||||
selenium:
|
|
||||||
# geckodriver-0.31 seems to have problems as of 2022 May 1
|
|
||||||
image: selenium/standalone-${{ matrix.browser == 'firefox' && 'firefox:99.0-geckodriver-0.30-20220427' || matrix.browser }}
|
|
||||||
ports:
|
|
||||||
- 4444:4444
|
|
||||||
options: --shm-size=2gb
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- name: Checkout
|
||||||
- uses: actions/cache@v1
|
uses: actions/checkout@v4
|
||||||
with:
|
- run: npm ci
|
||||||
path: ~/.npm
|
- name: Cypress run
|
||||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
uses: cypress-io/github-action@v6
|
||||||
restore-keys: |
|
with:
|
||||||
${{ runner.os }}-node-
|
build: npm run build
|
||||||
- run: npm ci
|
start: npm run start
|
||||||
- run: BROWSER=${{ matrix.browser }} TEST_NETWORK=testhost DOCKER_HOST=selenium npm run test
|
browser: ${{ matrix.browser }}
|
||||||
- if: ${{ matrix.browser == 'chrome' }}
|
|
||||||
run: ./node_modules/.bin/istanbul report --include build/coverage/coverage.json --dir build/coverage html lcov
|
|
||||||
- if: ${{ matrix.browser == 'chrome' }}
|
|
||||||
name: artifacts/coverage
|
|
||||||
uses: actions/upload-artifact@v1
|
|
||||||
with:
|
|
||||||
name: coverage
|
|
||||||
path: build/coverage
|
|
||||||
- name: artifacts/screenshots
|
|
||||||
uses: actions/upload-artifact@v1
|
|
||||||
with:
|
|
||||||
name: screenshots-${{ matrix.browser }}
|
|
||||||
path: build/screenshots
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ on:
|
|||||||
- 'v*'
|
- 'v*'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# publish docker to github registry
|
# publish docker to GitHub registry
|
||||||
deploy-docker:
|
deploy-docker:
|
||||||
name: deploy/docker
|
name: deploy/docker
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
@@ -21,8 +21,7 @@ jobs:
|
|||||||
os: [ubuntu-latest]
|
os: [ubuntu-latest]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login docker.pkg.github.com -u orangemug --password-stdin
|
- run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login docker.pkg.github.com -u orangemug --password-stdin
|
||||||
- run: docker build -t docker.pkg.github.com/maputnik/editor/editor:master .
|
- run: docker build -t docker.pkg.github.com/maputnik/editor/editor:master .
|
||||||
- run: docker push docker.pkg.github.com/maputnik/editor/editor:master
|
- run: docker push docker.pkg.github.com/maputnik/editor/editor:master
|
||||||
|
|
||||||
|
|||||||
@@ -33,3 +33,4 @@ public
|
|||||||
/errorShots
|
/errorShots
|
||||||
/old
|
/old
|
||||||
/build
|
/build
|
||||||
|
/cypress/screenshots
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
FROM node:10 as builder
|
FROM node:18 as builder
|
||||||
WORKDIR /maputnik
|
WORKDIR /maputnik
|
||||||
|
|
||||||
# Only copy package.json to prevent npm install from running on every build
|
# Only copy package.json to prevent npm install from running on every build
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
[github-action-ci]: https://github.com/maputnik/editor/actions?query=workflow%3Aci
|
[github-action-ci]: https://github.com/maputnik/editor/actions?query=workflow%3Aci
|
||||||
[license]: https://tldrlegal.com/license/mit-license
|
[license]: https://tldrlegal.com/license/mit-license
|
||||||
|
|
||||||
A free and open visual editor for the [Mapbox GL styles](https://www.mapbox.com/mapbox-gl-style-spec/)
|
A free and open visual editor for the [MapLibre GL styles](https://maplibre.org/maplibre-style-spec/)
|
||||||
targeted at developers and map designers.
|
targeted at developers and map designers.
|
||||||
|
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ The documentation can be found in the [Wiki](https://github.com/maputnik/editor/
|
|||||||
|
|
||||||
## Develop
|
## Develop
|
||||||
|
|
||||||
Maputnik is written in ES6 and is using [React](https://github.com/facebook/react) and [Mapbox GL JS](https://www.mapbox.com/mapbox-gl-js/api/).
|
Maputnik is written in ES6 and is using [React](https://github.com/facebook/react) and [MapLibre GL JS](https://maplibre.org/projects/maplibre-gl-js/).
|
||||||
|
|
||||||
We ensure building and developing Maputnik works with the [current active LTS Node.js version and above](https://github.com/nodejs/Release#release-schedule).
|
We ensure building and developing Maputnik works with the [current active LTS Node.js version and above](https://github.com/nodejs/Release#release-schedule).
|
||||||
|
|
||||||
@@ -76,9 +76,9 @@ npm run lint-styles
|
|||||||
|
|
||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
For testing we use [webdriverio](https://webdriver.io) and [selenium-standalone](https://github.com/webdriverio/selenium-standalone).
|
For E2E testing we use [Cypress](https://www.cypress.io/)
|
||||||
|
|
||||||
[selenium-standalone](https://github.com/webdriverio/selenium-standalone) starts a server that will launch browsers on your local machine. You need to have Java installed on your machine as well as *chrome* or *firefox*.
|
[Cypress](https://www.cypress.io/) doesn't starts a server so you'll need to start one manually by running `npm run start`.
|
||||||
|
|
||||||
Now open a terminal and run the following using *chrome*:
|
Now open a terminal and run the following using *chrome*:
|
||||||
|
|
||||||
@@ -87,10 +87,16 @@ npm run test
|
|||||||
```
|
```
|
||||||
or *firefox*:
|
or *firefox*:
|
||||||
```
|
```
|
||||||
BROWSER=firefox npm run test
|
npm run test -- --browser firefox
|
||||||
```
|
```
|
||||||
|
|
||||||
After some time you should see a browser launch which will be automated by the test runner.
|
See the following docs for more info: (Launching Browsers)[https://docs.cypress.io/guides/guides/launching-browsers]
|
||||||
|
|
||||||
|
You can also see the tests as they run or select which suites to run by executing:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm run cy:open
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Related Projects
|
## Related Projects
|
||||||
@@ -155,6 +161,5 @@ Sina Martinelli, Nicholas Doiron, Neil Cawse, Urs42, Benedikt Groß, Manuel Roth
|
|||||||
|
|
||||||
Maputnik is [licensed under MIT](LICENSE) and is Copyright (c) Lukas Martinelli and contributors.
|
Maputnik is [licensed under MIT](LICENSE) and is Copyright (c) Lukas Martinelli and contributors.
|
||||||
|
|
||||||
**Disclaimer** This project is not affiliated with Mapbox or Mapbox Studio. It is an independent style editor for the
|
**Disclaimer** This is an independent style editor.
|
||||||
open source technology in the Mapbox GL ecosystem.
|
|
||||||
As contributor please take extra care of not violating any Mapbox trademarks. Do not get inspired by Mapbox Studio and make your own decisions for a good style editor.
|
As contributor please take extra care of not violating any Mapbox trademarks. Do not get inspired by Mapbox Studio and make your own decisions for a good style editor.
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
var webpack = require("webpack");
|
|
||||||
var WebpackDevServer = require("webpack-dev-server");
|
|
||||||
var webpackConfig = require("./webpack.config");
|
|
||||||
var testConfig = require("../test/config/specs");
|
|
||||||
var artifacts = require("../test/artifacts");
|
|
||||||
|
|
||||||
|
|
||||||
var server;
|
|
||||||
var SCREENSHOT_PATH = artifacts.pathSync("screenshots");
|
|
||||||
|
|
||||||
exports.config = {
|
|
||||||
runner: 'local',
|
|
||||||
path: '/wd/hub',
|
|
||||||
specs: [
|
|
||||||
'./test/functional/index.js'
|
|
||||||
],
|
|
||||||
maxInstances: 10,
|
|
||||||
capabilities: [
|
|
||||||
{
|
|
||||||
maxInstances: 5,
|
|
||||||
browserName: (process.env.BROWSER || 'chrome'),
|
|
||||||
}
|
|
||||||
],
|
|
||||||
// geckodriver-0.31 seems to have problems as of 2022 May 1
|
|
||||||
services: process.env.DOCKER_HOST ? [] : [ ['selenium-standalone', { drivers: { firefox: '0.30.0', chrome: 'latest' } } ] ],
|
|
||||||
logLevel: 'info',
|
|
||||||
bail: 0,
|
|
||||||
screenshotPath: SCREENSHOT_PATH,
|
|
||||||
hostname: process.env.DOCKER_HOST || "0.0.0.0",
|
|
||||||
framework: 'mocha',
|
|
||||||
reporters: ['spec'],
|
|
||||||
mochaOpts: {
|
|
||||||
ui: 'bdd',
|
|
||||||
// Because we don't know how long the initial build will take...
|
|
||||||
timeout: 4*60*1000,
|
|
||||||
},
|
|
||||||
onPrepare: async function (config, capabilities) {
|
|
||||||
webpackConfig.devServer.host = testConfig.testNetwork;
|
|
||||||
webpackConfig.devServer.port = testConfig.port;
|
|
||||||
const compiler = webpack(webpackConfig);
|
|
||||||
server = new WebpackDevServer(webpackConfig.devServer, compiler);
|
|
||||||
await server.start();
|
|
||||||
},
|
|
||||||
onComplete: async function (exitCode, config, capabilities) {
|
|
||||||
await server.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -25,9 +25,6 @@ module.exports = {
|
|||||||
extensions: ['.js', '.jsx']
|
extensions: ['.js', '.jsx']
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
noParse: [
|
|
||||||
/mapbox-gl\/dist\/mapbox-gl.js/
|
|
||||||
],
|
|
||||||
rules: rules
|
rules: rules
|
||||||
},
|
},
|
||||||
node: {
|
node: {
|
||||||
|
|||||||
@@ -6,16 +6,14 @@ var HtmlWebpackInlineSVGPlugin = require('html-webpack-inline-svg-plugin');
|
|||||||
var WebpackCleanupPlugin = require('webpack-cleanup-plugin');
|
var WebpackCleanupPlugin = require('webpack-cleanup-plugin');
|
||||||
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
||||||
var CopyWebpackPlugin = require('copy-webpack-plugin');
|
var CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||||
var artifacts = require("../test/artifacts");
|
|
||||||
|
|
||||||
var OUTPATH = artifacts.pathSync("/build");
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
entry: {
|
entry: {
|
||||||
app: './src/index.jsx',
|
app: './src/index.jsx',
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
path: OUTPATH,
|
path: path.join(__dirname, '..', 'build', 'build'),
|
||||||
filename: '[name].[contenthash].js',
|
filename: '[name].[contenthash].js',
|
||||||
chunkFilename: '[contenthash].js'
|
chunkFilename: '[contenthash].js'
|
||||||
},
|
},
|
||||||
@@ -23,9 +21,6 @@ module.exports = {
|
|||||||
extensions: ['.js', '.jsx']
|
extensions: ['.js', '.jsx']
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
noParse: [
|
|
||||||
/mapbox-gl\/dist\/mapbox-gl.js/
|
|
||||||
],
|
|
||||||
rules: rules
|
rules: rules
|
||||||
},
|
},
|
||||||
node: {
|
node: {
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
const webpackProdConfig = require('./webpack.production.config');
|
const webpackProdConfig = require('./webpack.production.config');
|
||||||
const artifacts = require("../test/artifacts");
|
var path = require('path');
|
||||||
|
|
||||||
const OUTPATH = artifacts.pathSync("/profiling");
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
...webpackProdConfig,
|
...webpackProdConfig,
|
||||||
output: {
|
output: {
|
||||||
...webpackProdConfig.output,
|
...webpackProdConfig.output,
|
||||||
path: OUTPATH,
|
path: path.join(__dirname, '..', 'build', 'profiling'),
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
...webpackProdConfig.resolve,
|
...webpackProdConfig.resolve,
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { defineConfig } from "cypress";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
e2e: {
|
||||||
|
setupNodeEvents(on, config) {
|
||||||
|
// implement node event listeners here
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -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");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
@@ -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');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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'
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
})
|
||||||
@@ -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"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
@@ -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"));
|
||||||
|
})
|
||||||
|
})
|
||||||
|
});
|
||||||
@@ -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);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -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")
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
"version": 8,
|
"version": 8,
|
||||||
"name": "Test Style",
|
"name": "Test Style",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"maputnik:renderer": "mbgljs"
|
"maputnik:renderer": "mlgljs"
|
||||||
},
|
},
|
||||||
"sources": {},
|
"sources": {},
|
||||||
"glyphs": "https://example.local/fonts/{fontstack}/{range}.pbf",
|
"glyphs": "https://example.local/fonts/{fontstack}/{range}.pbf",
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
"version": 8,
|
"version": 8,
|
||||||
"name": "Test Style",
|
"name": "Test Style",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"maputnik:renderer": "mbgljs"
|
"maputnik:renderer": "mlgljs"
|
||||||
},
|
},
|
||||||
"sources": {},
|
"sources": {},
|
||||||
"glyphs": "https://example.local/fonts/{fontstack}/{range}.pbf",
|
"glyphs": "https://example.local/fonts/{fontstack}/{range}.pbf",
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
@@ -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')
|
||||||
Generated
+1778
-6641
File diff suppressed because it is too large
Load Diff
+14
-17
@@ -4,19 +4,19 @@
|
|||||||
"description": "A MapLibre GL visual style editor",
|
"description": "A MapLibre GL visual style editor",
|
||||||
"main": "''",
|
"main": "''",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"stats": "webpack --config config/webpack.production.config.js --progress=profile --json > stats.json",
|
"stats": "cross-env NODE_OPTIONS=--openssl-legacy-provider webpack --config config/webpack.production.config.js --progress=profile --json > stats.json",
|
||||||
"build": "webpack --config config/webpack.production.config.js --progress=profile --color",
|
"build": "cross-env NODE_OPTIONS=--openssl-legacy-provider webpack --config config/webpack.production.config.js --progress=profile --color",
|
||||||
"profiling-build": "webpack --config config/webpack.profiling.config.js --progress=profile --color",
|
"profiling-build": "cross-env NODE_OPTIONS=--openssl-legacy-provider webpack --config config/webpack.profiling.config.js --progress=profile --color",
|
||||||
"test": "cross-env NODE_ENV=test wdio config/wdio.conf.js",
|
"test": "cypress run",
|
||||||
"test-watch": "cross-env NODE_ENV=test wdio config/wdio.conf.js --watch",
|
"cy:open": "cypress open",
|
||||||
"start": "webpack-dev-server --progress=profile --color --config config/webpack.config.js",
|
"start": "cross-env NODE_OPTIONS=--openssl-legacy-provider webpack-dev-server --progress=profile --color --config config/webpack.config.js",
|
||||||
"start-prod": "webpack-dev-server --progress=profile --color --config config/webpack.production.config.js",
|
"start-prod": "cross-env NODE_OPTIONS=--openssl-legacy-provider webpack-dev-server --progress=profile --color --config config/webpack.production.config.js",
|
||||||
"start-sandbox": "webpack-dev-server --disable-host-check --host 0.0.0.0 --progress=profile --color --config config/webpack.production.config.js",
|
"start-sandbox": "cross-env NODE_OPTIONS=--openssl-legacy-provider webpack-dev-server --disable-host-check --host 0.0.0.0 --progress=profile --color --config config/webpack.production.config.js",
|
||||||
"lint-js": "eslint --ext js --ext jsx src test",
|
"lint-js": "eslint --ext js --ext jsx src test",
|
||||||
"lint-css": "stylelint \"src/styles/*.scss\"",
|
"lint-css": "stylelint \"src/styles/*.scss\"",
|
||||||
"lint": "npm run lint-js && npm run lint-css",
|
"lint": "npm run lint-js && npm run lint-css",
|
||||||
"storybook": "start-storybook -h 0.0.0.0 -p 6006",
|
"storybook": "cross-env NODE_OPTIONS=--openssl-legacy-provider start-storybook -h 0.0.0.0 -p 6006",
|
||||||
"build-storybook": "build-storybook -o build/storybook"
|
"build-storybook": "cross-env NODE_OPTIONS=--openssl-legacy-provider build-storybook -o build/storybook"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -133,11 +133,8 @@
|
|||||||
"@storybook/addons": "^6.4.20",
|
"@storybook/addons": "^6.4.20",
|
||||||
"@storybook/react": "^6.4.20",
|
"@storybook/react": "^6.4.20",
|
||||||
"@storybook/theming": "^6.4.20",
|
"@storybook/theming": "^6.4.20",
|
||||||
"@wdio/cli": "^7.19.3",
|
"@types/cors": "^2.8.17",
|
||||||
"@wdio/local-runner": "^7.19.3",
|
"@types/uuid": "^9.0.7",
|
||||||
"@wdio/mocha-framework": "^7.19.3",
|
|
||||||
"@wdio/selenium-standalone-service": "^7.19.1",
|
|
||||||
"@wdio/spec-reporter": "^7.19.1",
|
|
||||||
"babel-loader": "^8.2.4",
|
"babel-loader": "^8.2.4",
|
||||||
"babel-plugin-istanbul": "^6.1.1",
|
"babel-plugin-istanbul": "^6.1.1",
|
||||||
"babel-plugin-static-fs": "^3.0.0",
|
"babel-plugin-static-fs": "^3.0.0",
|
||||||
@@ -145,6 +142,7 @@
|
|||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"css-loader": "^5.2.7",
|
"css-loader": "^5.2.7",
|
||||||
|
"cypress": "^13.6.1",
|
||||||
"eslint": "^8.12.0",
|
"eslint": "^8.12.0",
|
||||||
"eslint-plugin-react": "^7.29.4",
|
"eslint-plugin-react": "^7.29.4",
|
||||||
"express": "^4.17.3",
|
"express": "^4.17.3",
|
||||||
@@ -163,9 +161,8 @@
|
|||||||
"stylelint-scss": "^4.2.0",
|
"stylelint-scss": "^4.2.0",
|
||||||
"svg-inline-loader": "^0.8.2",
|
"svg-inline-loader": "^0.8.2",
|
||||||
"transform-loader": "^0.2.4",
|
"transform-loader": "^0.2.4",
|
||||||
"typescript": "^4.6.3",
|
"typescript": "^4.9.5",
|
||||||
"uuid": "^8.3.2",
|
"uuid": "^8.3.2",
|
||||||
"webdriverio": "^7.19.3",
|
|
||||||
"webpack": "^4.46.0",
|
"webpack": "^4.46.0",
|
||||||
"webpack-bundle-analyzer": "^4.5.0",
|
"webpack-bundle-analyzer": "^4.5.0",
|
||||||
"webpack-cleanup-plugin": "^0.5.1",
|
"webpack-cleanup-plugin": "^0.5.1",
|
||||||
|
|||||||
+13
-13
@@ -9,7 +9,7 @@ import {arrayMoveMutable} from 'array-move'
|
|||||||
import url from 'url'
|
import url from 'url'
|
||||||
import hash from "string-hash";
|
import hash from "string-hash";
|
||||||
|
|
||||||
import MapMapboxGl from './MapMapboxGl'
|
import MapMaplibreGl from './MapMaplibreGl'
|
||||||
import MapOpenLayers from './MapOpenLayers'
|
import MapOpenLayers from './MapOpenLayers'
|
||||||
import LayerList from './LayerList'
|
import LayerList from './LayerList'
|
||||||
import LayerEditor from './LayerEditor'
|
import LayerEditor from './LayerEditor'
|
||||||
@@ -136,7 +136,7 @@ export default class App extends React.Component {
|
|||||||
{
|
{
|
||||||
key: "m",
|
key: "m",
|
||||||
handler: () => {
|
handler: () => {
|
||||||
document.querySelector(".mapboxgl-canvas").focus();
|
document.querySelector(".maplibregl-canvas").focus();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -220,7 +220,7 @@ export default class App extends React.Component {
|
|||||||
survey: false,
|
survey: false,
|
||||||
debug: false,
|
debug: false,
|
||||||
},
|
},
|
||||||
mapboxGlDebugOptions: {
|
maplibreGlDebugOptions: {
|
||||||
showTileBoundaries: false,
|
showTileBoundaries: false,
|
||||||
showCollisionBoxes: false,
|
showCollisionBoxes: false,
|
||||||
showOverdrawInspector: false,
|
showOverdrawInspector: false,
|
||||||
@@ -290,7 +290,7 @@ export default class App extends React.Component {
|
|||||||
// If we're changing renderer reset the map state.
|
// If we're changing renderer reset the map state.
|
||||||
if (
|
if (
|
||||||
property === 'maputnik:renderer' &&
|
property === 'maputnik:renderer' &&
|
||||||
value !== get(this.state.mapStyle, ['metadata', 'maputnik:renderer'], 'mbgljs')
|
value !== get(this.state.mapStyle, ['metadata', 'maputnik:renderer'], 'mlgljs')
|
||||||
) {
|
) {
|
||||||
this.setState({
|
this.setState({
|
||||||
mapState: 'map'
|
mapState: 'map'
|
||||||
@@ -547,7 +547,7 @@ export default class App extends React.Component {
|
|||||||
...styleObj,
|
...styleObj,
|
||||||
metadata: {
|
metadata: {
|
||||||
...styleObj.metadata,
|
...styleObj.metadata,
|
||||||
'maputnik:renderer': 'mbgljs'
|
'maputnik:renderer': 'mlgljs'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return changedStyle
|
return changedStyle
|
||||||
@@ -626,7 +626,7 @@ export default class App extends React.Component {
|
|||||||
|
|
||||||
_getRenderer () {
|
_getRenderer () {
|
||||||
const metadata = this.state.mapStyle.metadata || {};
|
const metadata = this.state.mapStyle.metadata || {};
|
||||||
return metadata['maputnik:renderer'] || 'mbgljs';
|
return metadata['maputnik:renderer'] || 'mlgljs';
|
||||||
}
|
}
|
||||||
|
|
||||||
onMapChange = (mapView) => {
|
onMapChange = (mapView) => {
|
||||||
@@ -665,9 +665,9 @@ export default class App extends React.Component {
|
|||||||
onLayerSelect={this.onLayerSelect}
|
onLayerSelect={this.onLayerSelect}
|
||||||
/>
|
/>
|
||||||
} else {
|
} else {
|
||||||
mapElement = <MapMapboxGl {...mapProps}
|
mapElement = <MapMaplibreGl {...mapProps}
|
||||||
onChange={this.onMapChange}
|
onChange={this.onMapChange}
|
||||||
options={this.state.mapboxGlDebugOptions}
|
options={this.state.maplibreGlDebugOptions}
|
||||||
inspectModeEnabled={this.state.mapState === "inspect"}
|
inspectModeEnabled={this.state.mapState === "inspect"}
|
||||||
highlightedLayer={this.state.mapStyle.layers[this.state.selectedLayerIndex]}
|
highlightedLayer={this.state.mapStyle.layers[this.state.selectedLayerIndex]}
|
||||||
onLayerSelect={this.onLayerSelect} />
|
onLayerSelect={this.onLayerSelect} />
|
||||||
@@ -800,10 +800,10 @@ export default class App extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onChangeMaboxGlDebug = (key, value) => {
|
onChangeMaplibreGlDebug = (key, value) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
mapboxGlDebugOptions: {
|
maplibreGlDebugOptions: {
|
||||||
...this.state.mapboxGlDebugOptions,
|
...this.state.maplibreGlDebugOptions,
|
||||||
[key]: value,
|
[key]: value,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -870,9 +870,9 @@ export default class App extends React.Component {
|
|||||||
const modals = <div>
|
const modals = <div>
|
||||||
<ModalDebug
|
<ModalDebug
|
||||||
renderer={this._getRenderer()}
|
renderer={this._getRenderer()}
|
||||||
mapboxGlDebugOptions={this.state.mapboxGlDebugOptions}
|
maplibreGlDebugOptions={this.state.maplibreGlDebugOptions}
|
||||||
openlayersDebugOptions={this.state.openlayersDebugOptions}
|
openlayersDebugOptions={this.state.openlayersDebugOptions}
|
||||||
onChangeMaboxGlDebug={this.onChangeMaboxGlDebug}
|
onChangeMaplibreGlDebug={this.onChangeMaplibreGlDebug}
|
||||||
onChangeOpenlayersDebug={this.onChangeOpenlayersDebug}
|
onChangeOpenlayersDebug={this.onChangeOpenlayersDebug}
|
||||||
isOpen={this.state.isOpen.debug}
|
isOpen={this.state.isOpen.debug}
|
||||||
onOpenToggle={this.toggleModal.bind(this, 'debug')}
|
onOpenToggle={this.toggleModal.bind(this, 'debug')}
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ export default class AppToolbar extends React.Component {
|
|||||||
|
|
||||||
onSkip = (target) => {
|
onSkip = (target) => {
|
||||||
if (target === "map") {
|
if (target === "map") {
|
||||||
document.querySelector(".mapboxgl-canvas").focus();
|
document.querySelector(".maplibregl-canvas").focus();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const el = document.querySelector("#skip-target-"+target);
|
const el = document.querySelector("#skip-target-"+target);
|
||||||
@@ -152,7 +152,7 @@ export default class AppToolbar extends React.Component {
|
|||||||
id: "inspect",
|
id: "inspect",
|
||||||
group: "general",
|
group: "general",
|
||||||
title: "Inspect",
|
title: "Inspect",
|
||||||
disabled: this.props.renderer !== 'mbgljs',
|
disabled: this.props.renderer === 'ol',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "filter-deuteranopia",
|
id: "filter-deuteranopia",
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ function createStyleFromFilter (filter) {
|
|||||||
"id": "tmp",
|
"id": "tmp",
|
||||||
"version": 8,
|
"version": 8,
|
||||||
"name": "Empty Style",
|
"name": "Empty Style",
|
||||||
"metadata": {"maputnik:renderer": "mbgljs"},
|
"metadata": {"maputnik:renderer": "mlgljs"},
|
||||||
"sources": {
|
"sources": {
|
||||||
"tmp": {
|
"tmp": {
|
||||||
"type": "geojson",
|
"type": "geojson",
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ function optionsLabelLength(options) {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Display any field from the Mapbox GL style spec and
|
/** Display any field from the Maplibre GL style spec and
|
||||||
* choose the correct field component based on the @{fieldSpec}
|
* choose the correct field component based on the @{fieldSpec}
|
||||||
* to display @{value}. */
|
* to display @{value}. */
|
||||||
export default class SpecField extends React.Component {
|
export default class SpecField extends React.Component {
|
||||||
|
|||||||
@@ -3,16 +3,16 @@ import PropTypes from 'prop-types'
|
|||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import MapLibreGl from 'maplibre-gl'
|
import MapLibreGl from 'maplibre-gl'
|
||||||
import MapboxInspect from 'mapbox-gl-inspect'
|
import MapboxInspect from 'mapbox-gl-inspect'
|
||||||
import MapMapboxGlLayerPopup from './MapMapboxGlLayerPopup'
|
import MapMaplibreGlLayerPopup from './MapMaplibreGlLayerPopup'
|
||||||
import MapMapboxGlFeaturePropertyPopup from './MapMapboxGlFeaturePropertyPopup'
|
import MapMaplibreGlFeaturePropertyPopup from './MapMaplibreGlFeaturePropertyPopup'
|
||||||
import tokens from '../config/tokens.json'
|
import tokens from '../config/tokens.json'
|
||||||
import colors from 'mapbox-gl-inspect/lib/colors'
|
import colors from 'mapbox-gl-inspect/lib/colors'
|
||||||
import Color from 'color'
|
import Color from 'color'
|
||||||
import ZoomControl from '../libs/zoomcontrol'
|
import ZoomControl from '../libs/zoomcontrol'
|
||||||
import { colorHighlightedLayer } from '../libs/highlight'
|
import { colorHighlightedLayer } from '../libs/highlight'
|
||||||
import 'maplibre-gl/dist/maplibre-gl.css'
|
import 'maplibre-gl/dist/maplibre-gl.css'
|
||||||
import '../mapboxgl.css'
|
import '../maplibregl.css'
|
||||||
import '../libs/mapbox-rtl'
|
import '../libs/maplibre-rtl'
|
||||||
|
|
||||||
|
|
||||||
const IS_SUPPORTED = MapLibreGl.supported();
|
const IS_SUPPORTED = MapLibreGl.supported();
|
||||||
@@ -52,7 +52,7 @@ function buildInspectStyle(originalMapStyle, coloredLayers, highlightedLayer) {
|
|||||||
return inspectStyle
|
return inspectStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class MapMapboxGl extends React.Component {
|
export default class MapMaplibreGl extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
onDataChange: PropTypes.func,
|
onDataChange: PropTypes.func,
|
||||||
onLayerSelect: PropTypes.func.isRequired,
|
onLayerSelect: PropTypes.func.isRequired,
|
||||||
@@ -69,7 +69,6 @@ export default class MapMapboxGl extends React.Component {
|
|||||||
onDataChange: () => {},
|
onDataChange: () => {},
|
||||||
onLayerSelect: () => {},
|
onLayerSelect: () => {},
|
||||||
onChange: () => {},
|
onChange: () => {},
|
||||||
mapboxAccessToken: tokens.mapbox,
|
|
||||||
options: {},
|
options: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +85,7 @@ export default class MapMapboxGl extends React.Component {
|
|||||||
|
|
||||||
if(!this.state.map) return
|
if(!this.state.map) return
|
||||||
|
|
||||||
//Mapbox GL now does diffing natively so we don't need to calculate
|
//Maplibre GL now does diffing natively so we don't need to calculate
|
||||||
//the necessary operations ourselves!
|
//the necessary operations ourselves!
|
||||||
this.state.map.setStyle(
|
this.state.map.setStyle(
|
||||||
this.props.replaceAccessTokens(props.mapStyle),
|
this.props.replaceAccessTokens(props.mapStyle),
|
||||||
@@ -120,7 +119,7 @@ export default class MapMapboxGl extends React.Component {
|
|||||||
if (map) {
|
if (map) {
|
||||||
if (this.props.inspectModeEnabled) {
|
if (this.props.inspectModeEnabled) {
|
||||||
// HACK: We need to work out why we need to do this and what's causing
|
// HACK: We need to work out why we need to do this and what's causing
|
||||||
// this error. I'm assuming an issue with mapbox-gl update and
|
// this error. I'm assuming an issue with maplibre-gl update and
|
||||||
// mapbox-gl-inspect.
|
// mapbox-gl-inspect.
|
||||||
try {
|
try {
|
||||||
this.state.inspect.render();
|
this.state.inspect.render();
|
||||||
@@ -182,9 +181,9 @@ export default class MapMapboxGl extends React.Component {
|
|||||||
buildInspectStyle: (originalMapStyle, coloredLayers) => buildInspectStyle(originalMapStyle, coloredLayers, this.props.highlightedLayer),
|
buildInspectStyle: (originalMapStyle, coloredLayers) => buildInspectStyle(originalMapStyle, coloredLayers, this.props.highlightedLayer),
|
||||||
renderPopup: features => {
|
renderPopup: features => {
|
||||||
if(this.props.inspectModeEnabled) {
|
if(this.props.inspectModeEnabled) {
|
||||||
return renderPopup(<MapMapboxGlFeaturePropertyPopup features={features} />, tmpNode);
|
return renderPopup(<MapMaplibreGlFeaturePropertyPopup features={features} />, tmpNode);
|
||||||
} else {
|
} else {
|
||||||
return renderPopup(<MapMapboxGlLayerPopup features={features} onLayerSelect={this.onLayerSelectById} zoom={this.state.zoom} />, tmpNode);
|
return renderPopup(<MapMaplibreGlLayerPopup features={features} onLayerSelect={this.onLayerSelectById} zoom={this.state.zoom} />, tmpNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -238,7 +237,7 @@ export default class MapMapboxGl extends React.Component {
|
|||||||
className="maputnik-map maputnik-map--error"
|
className="maputnik-map maputnik-map--error"
|
||||||
>
|
>
|
||||||
<div className="maputnik-map__error-message">
|
<div className="maputnik-map__error-message">
|
||||||
Error: Cannot load MapboxGL, WebGL is either unsupported or disabled
|
Error: Cannot load MaplibreGL, WebGL is either unsupported or disabled
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ import {throttle} from 'lodash';
|
|||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import { loadJSON } from '../libs/urlopen'
|
import { loadJSON } from '../libs/urlopen'
|
||||||
|
|
||||||
import MapMapboxGlLayerPopup from './MapMapboxGlLayerPopup';
|
import MapMaplibreGlLayerPopup from './MapMaplibreGlLayerPopup';
|
||||||
|
|
||||||
import 'ol/ol.css'
|
import 'ol/ol.css'
|
||||||
import {apply} from 'ol-mapbox-style';
|
import {apply} from 'ol-mapbox-style';
|
||||||
@@ -146,13 +146,13 @@ export default class MapOpenLayers extends React.Component {
|
|||||||
className="maputnik-popup"
|
className="maputnik-popup"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
className="mapboxgl-popup-close-button"
|
className="maplibregl-popup-close-button"
|
||||||
onClick={this.closeOverlay}
|
onClick={this.closeOverlay}
|
||||||
aria-label="Close popup"
|
aria-label="Close popup"
|
||||||
>
|
>
|
||||||
×
|
×
|
||||||
</button>
|
</button>
|
||||||
<MapMapboxGlLayerPopup
|
<MapMaplibreGlLayerPopup
|
||||||
features={this.state.selectedFeatures || []}
|
features={this.state.selectedFeatures || []}
|
||||||
onLayerSelect={this.props.onLayerSelect}
|
onLayerSelect={this.props.onLayerSelect}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export default class ModalDebug extends React.Component {
|
|||||||
onChangeMaboxGlDebug: PropTypes.func.isRequired,
|
onChangeMaboxGlDebug: PropTypes.func.isRequired,
|
||||||
onChangeOpenlayersDebug: PropTypes.func.isRequired,
|
onChangeOpenlayersDebug: PropTypes.func.isRequired,
|
||||||
onOpenToggle: PropTypes.func.isRequired,
|
onOpenToggle: PropTypes.func.isRequired,
|
||||||
mapboxGlDebugOptions: PropTypes.object,
|
maplibreGlDebugOptions: PropTypes.object,
|
||||||
openlayersDebugOptions: PropTypes.object,
|
openlayersDebugOptions: PropTypes.object,
|
||||||
mapView: PropTypes.object,
|
mapView: PropTypes.object,
|
||||||
}
|
}
|
||||||
@@ -31,9 +31,9 @@ export default class ModalDebug extends React.Component {
|
|||||||
>
|
>
|
||||||
<section className="maputnik-modal-section maputnik-modal-shortcuts">
|
<section className="maputnik-modal-section maputnik-modal-shortcuts">
|
||||||
<h1>Options</h1>
|
<h1>Options</h1>
|
||||||
{this.props.renderer === 'mbgljs' &&
|
{this.props.renderer === 'mlgljs' &&
|
||||||
<ul>
|
<ul>
|
||||||
{Object.entries(this.props.mapboxGlDebugOptions).map(([key, val]) => {
|
{Object.entries(this.props.maplibreGlDebugOptions).map(([key, val]) => {
|
||||||
return <li key={key}>
|
return <li key={key}>
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" checked={val} onClick={(e) => this.props.onChangeMaboxGlDebug(key, e.target.checked)} /> {key}
|
<input type="checkbox" checked={val} onClick={(e) => this.props.onChangeMaboxGlDebug(key, e.target.checked)} /> {key}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import style from '../libs/style'
|
|||||||
import fieldSpecAdditional from '../libs/field-spec-additional'
|
import fieldSpecAdditional from '../libs/field-spec-additional'
|
||||||
|
|
||||||
|
|
||||||
const MAPBOX_GL_VERSION = pkgLockJson.dependencies["mapbox-gl"].version;
|
const MAPLIBRE_GL_VERSION = pkgLockJson.dependencies["maplibre-gl"].version;
|
||||||
|
|
||||||
|
|
||||||
export default class ModalExport extends React.Component {
|
export default class ModalExport extends React.Component {
|
||||||
@@ -58,8 +58,8 @@ export default class ModalExport extends React.Component {
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>${htmlTitle}</title>
|
<title>${htmlTitle}</title>
|
||||||
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
|
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
|
||||||
<script src="https://api.mapbox.com/mapbox-gl-js/v${MAPBOX_GL_VERSION}/mapbox-gl.js"></script>
|
<script src="https://unpkg.com/maplibre-gl@${MAPLIBRE_GL_VERSION}/dist/maplibre-gl.js"></script>
|
||||||
<link href="https://api.mapbox.com/mapbox-gl-js/v${MAPBOX_GL_VERSION}/mapbox-gl.css" rel="stylesheet" />
|
<link href="https://unpkg.com/maplibre-gl@${MAPLIBRE_GL_VERSION}/dist/maplibre-gl.css" rel="stylesheet" />
|
||||||
<style>
|
<style>
|
||||||
body { margin: 0; padding: 0; }
|
body { margin: 0; padding: 0; }
|
||||||
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
|
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
|
||||||
@@ -68,12 +68,11 @@ export default class ModalExport extends React.Component {
|
|||||||
<body>
|
<body>
|
||||||
<div id="map"></div>
|
<div id="map"></div>
|
||||||
<script>
|
<script>
|
||||||
mapboxgl.accessToken = 'access_token';
|
const map = new maplibregl.Map({
|
||||||
const map = new mapboxgl.Map({
|
|
||||||
container: 'map',
|
container: 'map',
|
||||||
style: ${tokenStyle},
|
style: ${tokenStyle},
|
||||||
});
|
});
|
||||||
map.addControl(new mapboxgl.NavigationControl());
|
map.addControl(new maplibregl.NavigationControl());
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -119,12 +118,6 @@ export default class ModalExport extends React.Component {
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<FieldString
|
|
||||||
label={fieldSpecAdditional.maputnik.mapbox_access_token.label}
|
|
||||||
fieldSpec={fieldSpecAdditional.maputnik.mapbox_access_token}
|
|
||||||
value={(this.props.mapStyle.metadata || {})['maputnik:mapbox_access_token']}
|
|
||||||
onChange={this.changeMetadataProperty.bind(this, "maputnik:mapbox_access_token")}
|
|
||||||
/>
|
|
||||||
<FieldString
|
<FieldString
|
||||||
label={fieldSpecAdditional.maputnik.maptiler_access_token.label}
|
label={fieldSpecAdditional.maputnik.maptiler_access_token.label}
|
||||||
fieldSpec={fieldSpecAdditional.maputnik.maptiler_access_token}
|
fieldSpec={fieldSpecAdditional.maputnik.maptiler_access_token}
|
||||||
|
|||||||
@@ -117,14 +117,6 @@ export default class ModalSettings extends React.Component {
|
|||||||
onChange={this.changeStyleProperty.bind(this, "glyphs")}
|
onChange={this.changeStyleProperty.bind(this, "glyphs")}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FieldString {...inputProps}
|
|
||||||
label={fieldSpecAdditional.maputnik.mapbox_access_token.label}
|
|
||||||
fieldSpec={fieldSpecAdditional.maputnik.mapbox_access_token}
|
|
||||||
data-wd-key="modal:settings.maputnik:mapbox_access_token"
|
|
||||||
value={metadata['maputnik:mapbox_access_token']}
|
|
||||||
onChange={onChangeMetadataProperty.bind(this, "maputnik:mapbox_access_token")}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FieldString {...inputProps}
|
<FieldString {...inputProps}
|
||||||
label={fieldSpecAdditional.maputnik.maptiler_access_token.label}
|
label={fieldSpecAdditional.maputnik.maptiler_access_token.label}
|
||||||
fieldSpec={fieldSpecAdditional.maputnik.maptiler_access_token}
|
fieldSpec={fieldSpecAdditional.maputnik.maptiler_access_token}
|
||||||
@@ -241,10 +233,10 @@ export default class ModalSettings extends React.Component {
|
|||||||
fieldSpec={fieldSpecAdditional.maputnik.style_renderer}
|
fieldSpec={fieldSpecAdditional.maputnik.style_renderer}
|
||||||
data-wd-key="modal:settings.maputnik:renderer"
|
data-wd-key="modal:settings.maputnik:renderer"
|
||||||
options={[
|
options={[
|
||||||
['mbgljs', 'MapboxGL JS'],
|
['mlgljs', 'MapLibreGL JS'],
|
||||||
['ol', 'Open Layers (experimental)'],
|
['ol', 'Open Layers (experimental)'],
|
||||||
]}
|
]}
|
||||||
value={metadata['maputnik:renderer'] || 'mbgljs'}
|
value={metadata['maputnik:renderer'] || 'mlgljs'}
|
||||||
onChange={onChangeMetadataProperty.bind(this, 'maputnik:renderer')}
|
onChange={onChangeMetadataProperty.bind(this, 'maputnik:renderer')}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ class AddSource extends React.Component {
|
|||||||
}
|
}
|
||||||
case 'geojson_json': return {
|
case 'geojson_json': return {
|
||||||
type: 'geojson',
|
type: 'geojson',
|
||||||
|
cluster: source.cluster || false,
|
||||||
data: {}
|
data: {}
|
||||||
}
|
}
|
||||||
case 'tilejson_vector': return {
|
case 'tilejson_vector': return {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import FieldSelect from './FieldSelect'
|
|||||||
import FieldDynamicArray from './FieldDynamicArray'
|
import FieldDynamicArray from './FieldDynamicArray'
|
||||||
import FieldArray from './FieldArray'
|
import FieldArray from './FieldArray'
|
||||||
import FieldJson from './FieldJson'
|
import FieldJson from './FieldJson'
|
||||||
|
import FieldCheckbox from './FieldCheckbox'
|
||||||
|
|
||||||
|
|
||||||
class TileJSONSourceEditor extends React.Component {
|
class TileJSONSourceEditor extends React.Component {
|
||||||
@@ -80,7 +81,7 @@ class TileURLSourceEditor extends React.Component {
|
|||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -205,23 +206,35 @@ class GeoJSONSourceFieldJsonEditor extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <Block label={"GeoJSON"} fieldSpec={latest.source_geojson.data}>
|
return <div>
|
||||||
<FieldJson
|
<Block label={"GeoJSON"} fieldSpec={latest.source_geojson.data}>
|
||||||
layer={this.props.source.data}
|
<FieldJson
|
||||||
maxHeight={200}
|
layer={this.props.source.data}
|
||||||
mode={{
|
maxHeight={200}
|
||||||
name: "javascript",
|
mode={{
|
||||||
json: true
|
name: "javascript",
|
||||||
}}
|
json: true
|
||||||
lint={true}
|
}}
|
||||||
onChange={data => {
|
lint={true}
|
||||||
|
onChange={data => {
|
||||||
|
this.props.onChange({
|
||||||
|
...this.props.source,
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Block>
|
||||||
|
<FieldCheckbox
|
||||||
|
label={'Cluster'}
|
||||||
|
value={this.props.source.cluster}
|
||||||
|
onChange={cluster => {
|
||||||
this.props.onChange({
|
this.props.onChange({
|
||||||
...this.props.source,
|
...this.props.source,
|
||||||
data,
|
cluster: cluster,
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Block>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
{
|
{
|
||||||
"mapbox": "pk.eyJ1IjoibW9yZ2Vua2FmZmVlIiwiYSI6ImNpeHJmNXNmZTAwNHIycXBid2NqdTJibjMifQ.Dv1-GDpTWi0NP6xW9Fct1w",
|
|
||||||
"openmaptiles": "KDhMfHvorAFkFe64wlZb",
|
"openmaptiles": "KDhMfHvorAFkFe64wlZb",
|
||||||
"thunderforest": "b71f7f0ba4064f5eb9e903859a9cf5c6"
|
"thunderforest": "b71f7f0ba4064f5eb9e903859a9cf5c6"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
const spec = {
|
const spec = {
|
||||||
maputnik: {
|
maputnik: {
|
||||||
mapbox_access_token: {
|
|
||||||
label: "Mapbox Access Token",
|
|
||||||
doc: "Public access token for Mapbox services."
|
|
||||||
},
|
|
||||||
maptiler_access_token: {
|
maptiler_access_token: {
|
||||||
label: "MapTiler Access Token",
|
label: "MapTiler Access Token",
|
||||||
doc: "Public access token for MapTiler Cloud."
|
doc: "Public access token for MapTiler Cloud."
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ export function changeProperty(layer, group, property, newValue) {
|
|||||||
if(group) {
|
if(group) {
|
||||||
const newLayer = {
|
const newLayer = {
|
||||||
...layer,
|
...layer,
|
||||||
// Change object so the diff works in ./src/components/map/MapboxGlMap.jsx
|
// Change object so the diff works in ./src/components/map/MaplibreGlMap.jsx
|
||||||
[group]: {
|
[group]: {
|
||||||
...layer[group]
|
...layer[group]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ export default class LayerWatcher {
|
|||||||
const previousSources = { ...this._sources }
|
const previousSources = { ...this._sources }
|
||||||
|
|
||||||
Object.keys(map.style.sourceCaches).forEach(sourceId => {
|
Object.keys(map.style.sourceCaches).forEach(sourceId => {
|
||||||
//NOTE: This heavily depends on the internal API of Mapbox GL
|
//NOTE: This heavily depends on the internal API of Maplibre GL
|
||||||
//so this breaks between Mapbox GL JS releases
|
//so this breaks between Maplibre GL JS releases
|
||||||
this._sources[sourceId] = map.style.sourceCaches[sourceId]._source.vectorLayerIds
|
this._sources[sourceId] = map.style.sourceCaches[sourceId]._source.vectorLayerIds
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -116,7 +116,6 @@ function stripAccessTokens(mapStyle) {
|
|||||||
const changedMetadata = {
|
const changedMetadata = {
|
||||||
...mapStyle.metadata
|
...mapStyle.metadata
|
||||||
};
|
};
|
||||||
delete changedMetadata['maputnik:mapbox_access_token'];
|
|
||||||
delete changedMetadata['maputnik:openmaptiles_access_token'];
|
delete changedMetadata['maputnik:openmaptiles_access_token'];
|
||||||
return {
|
return {
|
||||||
...mapStyle,
|
...mapStyle,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ export default class ZoomControl {
|
|||||||
onAdd(map) {
|
onAdd(map) {
|
||||||
this._map = map;
|
this._map = map;
|
||||||
this._container = document.createElement('div');
|
this._container = document.createElement('div');
|
||||||
this._container.className = 'mapboxgl-ctrl mapboxgl-ctrl-group mapboxgl-ctrl-zoom';
|
this._container.className = 'maplibregl-ctrl maplibregl-ctrl-group maplibregl-ctrl-zoom';
|
||||||
this._container.innerHTML = `
|
this._container.innerHTML = `
|
||||||
Zoom: <span></span>
|
Zoom: <span></span>
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -1,93 +1,91 @@
|
|||||||
/* TODO */
|
.maplibregl-popup-anchor-top .maplibregl-popup-tip {
|
||||||
|
|
||||||
.mapboxgl-popup-anchor-top .mapboxgl-popup-tip {
|
|
||||||
border-bottom-color: rgb(28, 31, 36);
|
border-bottom-color: rgb(28, 31, 36);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapboxgl-popup-anchor-left .mapboxgl-popup-tip {
|
.maplibregl-popup-anchor-left .maplibregl-popup-tip {
|
||||||
border-right-color: rgb(28, 31, 36);
|
border-right-color: rgb(28, 31, 36);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapboxgl-popup-anchor-right .mapboxgl-popup-tip {
|
.maplibregl-popup-anchor-right .maplibregl-popup-tip {
|
||||||
border-left-color: rgb(28, 31, 36);
|
border-left-color: rgb(28, 31, 36);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapboxgl-popup-anchor-bottom .mapboxgl-popup-tip {
|
.maplibregl-popup-anchor-bottom .maplibregl-popup-tip {
|
||||||
border-top-color: rgb(28, 31, 36);
|
border-top-color: rgb(28, 31, 36);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapboxgl-popup-anchor-top-left .mapboxgl-popup-tip {
|
.maplibregl-popup-anchor-top-left .maplibregl-popup-tip {
|
||||||
border-bottom-color: rgb(28, 31, 36);
|
border-bottom-color: rgb(28, 31, 36);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapboxgl-popup-anchor-top-right .mapboxgl-popup-tip {
|
.maplibregl-popup-anchor-top-right .maplibregl-popup-tip {
|
||||||
border-bottom-color: rgb(28, 31, 36);
|
border-bottom-color: rgb(28, 31, 36);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapboxgl-popup-anchor-bottom-left .mapboxgl-popup-tip {
|
.maplibregl-popup-anchor-bottom-left .maplibregl-popup-tip {
|
||||||
border-top-color: rgb(28, 31, 36);
|
border-top-color: rgb(28, 31, 36);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapboxgl-popup-anchor-bottom-right .mapboxgl-popup-tip {
|
.maplibregl-popup-anchor-bottom-right .maplibregl-popup-tip {
|
||||||
border-top-color: rgb(28, 31, 36);
|
border-top-color: rgb(28, 31, 36);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapboxgl-popup-content {
|
.maplibregl-popup-content {
|
||||||
background-color: rgb(28, 31, 36);
|
background-color: rgb(28, 31, 36);
|
||||||
box-shadow: rgba(0, 0, 0, 0.298039) 0px 0px 5px 0px;
|
box-shadow: rgba(0, 0, 0, 0.298039) 0px 0px 5px 0px;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapboxgl-popup-close-button {
|
.maplibregl-popup-close-button {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapboxgl-ctrl-zoom {
|
.maplibregl-ctrl-zoom {
|
||||||
color: #a4a4a4;
|
color: #a4a4a4;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapboxgl-ctrl-group {
|
.maplibregl-ctrl-group {
|
||||||
background: rgb(28, 31, 36);
|
background: rgb(28, 31, 36);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapboxgl-ctrl-group > button {
|
.maplibregl-ctrl-group > button {
|
||||||
background-color: rgb(28, 31, 36);
|
background-color: rgb(28, 31, 36);
|
||||||
border-color: rgb(28, 31, 36);
|
border-color: rgb(28, 31, 36);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapboxgl-ctrl button:not(:disabled):hover {
|
.maplibregl-ctrl button:not(:disabled):hover {
|
||||||
background-color: rgb(86, 83, 83);
|
background-color: rgb(86, 83, 83);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapboxgl-ctrl-zoom-in {
|
.maplibregl-ctrl-zoom-in {
|
||||||
border-radius: 4px 4px 0 0;
|
border-radius: 4px 4px 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapboxgl-ctrl-compass {
|
.maplibregl-ctrl-compass {
|
||||||
border-radius: 0 0 4px 4px;
|
border-radius: 0 0 4px 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapboxgl-ctrl button.mapboxgl-ctrl-zoom-in .mapboxgl-ctrl-icon {
|
.maplibregl-ctrl button.maplibregl-ctrl-zoom-in .maplibregl-ctrl-icon {
|
||||||
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0A%20%20%3Cpath%20style%3D%27fill%3A%23a4a4a4%3B%27%20d%3D%27M%2010%206%20C%209.446%206%209%206.4459904%209%207%20L%209%209%20L%207%209%20C%206.446%209%206%209.446%206%2010%20C%206%2010.554%206.446%2011%207%2011%20L%209%2011%20L%209%2013%20C%209%2013.55401%209.446%2014%2010%2014%20C%2010.554%2014%2011%2013.55401%2011%2013%20L%2011%2011%20L%2013%2011%20C%2013.554%2011%2014%2010.554%2014%2010%20C%2014%209.446%2013.554%209%2013%209%20L%2011%209%20L%2011%207%20C%2011%206.4459904%2010.554%206%2010%206%20z%27%20%2F%3E%0A%3C%2Fsvg%3E%0A")
|
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0A%20%20%3Cpath%20style%3D%27fill%3A%23a4a4a4%3B%27%20d%3D%27M%2010%206%20C%209.446%206%209%206.4459904%209%207%20L%209%209%20L%207%209%20C%206.446%209%206%209.446%206%2010%20C%206%2010.554%206.446%2011%207%2011%20L%209%2011%20L%209%2013%20C%209%2013.55401%209.446%2014%2010%2014%20C%2010.554%2014%2011%2013.55401%2011%2013%20L%2011%2011%20L%2013%2011%20C%2013.554%2011%2014%2010.554%2014%2010%20C%2014%209.446%2013.554%209%2013%209%20L%2011%209%20L%2011%207%20C%2011%206.4459904%2010.554%206%2010%206%20z%27%20%2F%3E%0A%3C%2Fsvg%3E%0A")
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapboxgl-ctrl button.mapboxgl-ctrl-zoom-out .mapboxgl-ctrl-icon {
|
.maplibregl-ctrl button.maplibregl-ctrl-zoom-out .maplibregl-ctrl-icon {
|
||||||
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0A%20%20%3Cpath%20style%3D%27fill%3A%23a4a4a4%3B%27%20d%3D%27m%207%2C9%20c%20-0.554%2C0%20-1%2C0.446%20-1%2C1%200%2C0.554%200.446%2C1%201%2C1%20l%206%2C0%20c%200.554%2C0%201%2C-0.446%201%2C-1%200%2C-0.554%20-0.446%2C-1%20-1%2C-1%20z%27%20%2F%3E%0A%3C%2Fsvg%3E%0A")
|
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20viewBox%3D%270%200%2020%2020%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%0A%20%20%3Cpath%20style%3D%27fill%3A%23a4a4a4%3B%27%20d%3D%27m%207%2C9%20c%20-0.554%2C0%20-1%2C0.446%20-1%2C1%200%2C0.554%200.446%2C1%201%2C1%20l%206%2C0%20c%200.554%2C0%201%2C-0.446%201%2C-1%200%2C-0.554%20-0.446%2C-1%20-1%2C-1%20z%27%20%2F%3E%0A%3C%2Fsvg%3E%0A")
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapboxgl-ctrl button.mapboxgl-ctrl-compass .mapboxgl-ctrl-icon {
|
.maplibregl-ctrl button.maplibregl-ctrl-compass .maplibregl-ctrl-icon {
|
||||||
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%0A%09%3Cpolygon%20fill%3D%27%23a4a4a4%27%20points%3D%276%2C9%2010%2C1%2014%2C9%27%2F%3E%0A%09%3Cpolygon%20fill%3D%27%23545454%27%20points%3D%276%2C11%2010%2C19%2014%2C11%20%27%2F%3E%0A%3C%2Fsvg%3E");
|
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%0A%09%3Cpolygon%20fill%3D%27%23a4a4a4%27%20points%3D%276%2C9%2010%2C1%2014%2C9%27%2F%3E%0A%09%3Cpolygon%20fill%3D%27%23545454%27%20points%3D%276%2C11%2010%2C19%2014%2C11%20%27%2F%3E%0A%3C%2Fsvg%3E");
|
||||||
background-size: 18px;
|
background-size: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapboxgl-ctrl-inspect {
|
.maplibregl-ctrl-inspect {
|
||||||
background-image: url('data:image/svg+xml;charset=utf8,<svg%20xmlns="http://www.w3.org/2000/svg"%20fill="#8e8e8e%22%20preserveAspectRatio=%22xMidYMid%20meet%22%20viewBox=%22-10%20-10%2060%2060%22%3E%3Cg%3E%3Cpath%20d=%22m15%2021.6q0-2%201.5-3.5t3.5-1.5%203.5%201.5%201.5%203.5-1.5%203.6-3.5%201.4-3.5-1.4-1.5-3.6z%20m18.4%2011.1l-6.4-6.5q1.4-2.1%201.4-4.6%200-3.4-2.5-5.8t-5.9-2.4-5.9%202.4-2.5%205.8%202.5%205.9%205.9%202.5q2.4%200%204.6-1.4l7.4%207.4q-0.9%200.6-2%200.6h-20q-1.3%200-2.3-0.9t-1.1-2.3l0.1-26.8q0-1.3%201-2.3t2.3-0.9h13.4l10%2010v19.3z%22%3E%3C/path%3E%3C/g%3E%3C/svg%3E');
|
background-image: url('data:image/svg+xml;charset=utf8,<svg%20xmlns="http://www.w3.org/2000/svg"%20fill="#8e8e8e%22%20preserveAspectRatio=%22xMidYMid%20meet%22%20viewBox=%22-10%20-10%2060%2060%22%3E%3Cg%3E%3Cpath%20d=%22m15%2021.6q0-2%201.5-3.5t3.5-1.5%203.5%201.5%201.5%203.5-1.5%203.6-3.5%201.4-3.5-1.4-1.5-3.6z%20m18.4%2011.1l-6.4-6.5q1.4-2.1%201.4-4.6%200-3.4-2.5-5.8t-5.9-2.4-5.9%202.4-2.5%205.8%202.5%205.9%205.9%202.5q2.4%200%204.6-1.4l7.4%207.4q-0.9%200.6-2%200.6h-20q-1.3%200-2.3-0.9t-1.1-2.3l0.1-26.8q0-1.3%201-2.3t2.3-0.9h13.4l10%2010v19.3z%22%3E%3C/path%3E%3C/g%3E%3C/svg%3E');
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapboxgl-ctrl-map {
|
.maplibregl-ctrl-map {
|
||||||
background-image: url('data:image/svg+xml;charset=utf8,<svg%20xmlns="http://www.w3.org/2000/svg"%20fill="#8e8e8e%22%20viewBox=%22-10%20-10%2060%2060%22%20preserveAspectRatio=%22xMidYMid%20meet%22%3E%3Cg%3E%3Cpath%20d=%22m25%2031.640000000000004v-19.766666666666673l-10-3.511666666666663v19.766666666666666z%20m9.140000000000008-26.640000000000004q0.8599999999999923%200%200.8599999999999923%200.8600000000000003v25.156666666666666q0%200.625-0.625%200.783333333333335l-9.375%203.1999999999999993-10-3.5133333333333354-8.906666666666668%203.4383333333333326-0.2333333333333334%200.07833333333333314q-0.8616666666666664%200-0.8616666666666664-0.8599999999999994v-25.156666666666663q0-0.625%200.6233333333333331-0.7833333333333332l9.378333333333334-3.198333333333334%2010%203.5133333333333336%208.905000000000001-3.4383333333333344z%22%3E%3C/path%3E%3C/g%3E%3C/svg%3E');
|
background-image: url('data:image/svg+xml;charset=utf8,<svg%20xmlns="http://www.w3.org/2000/svg"%20fill="#8e8e8e%22%20viewBox=%22-10%20-10%2060%2060%22%20preserveAspectRatio=%22xMidYMid%20meet%22%3E%3Cg%3E%3Cpath%20d=%22m25%2031.640000000000004v-19.766666666666673l-10-3.511666666666663v19.766666666666666z%20m9.140000000000008-26.640000000000004q0.8599999999999923%200%200.8599999999999923%200.8600000000000003v25.156666666666666q0%200.625-0.625%200.783333333333335l-9.375%203.1999999999999993-10-3.5133333333333354-8.906666666666668%203.4383333333333326-0.2333333333333334%200.07833333333333314q-0.8616666666666664%200-0.8616666666666664-0.8599999999999994v-25.156666666666663q0-0.625%200.6233333333333331-0.7833333333333332l9.378333333333334-3.198333333333334%2010%203.5133333333333336%208.905000000000001-3.4383333333333344z%22%3E%3C/path%3E%3C/g%3E%3C/svg%3E');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,13 +18,6 @@
|
|||||||
@import 'codemirror';
|
@import 'codemirror';
|
||||||
@import 'react-collapse';
|
@import 'react-collapse';
|
||||||
|
|
||||||
/**
|
|
||||||
* Hacks for webdriverio isVisibleWithinViewport
|
|
||||||
*/
|
|
||||||
#app {
|
|
||||||
height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.maputnik-layout {
|
.maputnik-layout {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import MapMapboxGl from '../src/components/MapMapboxGl';
|
import MapMaplibreGl from '../src/components/MapMaplibreGl';
|
||||||
import {action} from '@storybook/addon-actions';
|
import {action} from '@storybook/addon-actions';
|
||||||
import {Wrapper} from './ui';
|
import {Wrapper} from './ui';
|
||||||
import {withA11y} from '@storybook/addon-a11y';
|
import {withA11y} from '@storybook/addon-a11y';
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: 'MapMapboxGl',
|
title: 'MapMaplibreGl',
|
||||||
component: MapMapboxGl,
|
component: MapMaplibreGl,
|
||||||
decorators: [withA11y],
|
decorators: [withA11y],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ const mapStyle = {
|
|||||||
|
|
||||||
export const Basic = () => {
|
export const Basic = () => {
|
||||||
return <div style={{height: "100vh", width: "100vw"}}>
|
return <div style={{height: "100vh", width: "100vw"}}>
|
||||||
<MapMapboxGl
|
<MapMaplibreGl
|
||||||
mapStyle={mapStyle}
|
mapStyle={mapStyle}
|
||||||
inspectModeEnabled={false}
|
inspectModeEnabled={false}
|
||||||
replaceAccessTokens={(s) => s}
|
replaceAccessTokens={(s) => s}
|
||||||
@@ -16,8 +16,8 @@ export const Basic = () => (
|
|||||||
<div style={{maxHeight: "200px"}}>
|
<div style={{maxHeight: "200px"}}>
|
||||||
<ModalDebug
|
<ModalDebug
|
||||||
isOpen={true}
|
isOpen={true}
|
||||||
renderer="mbgljs"
|
renderer="mlgljs"
|
||||||
mapboxGlDebugOptions={{}}
|
maplibreGlDebugOptions={{}}
|
||||||
mapView={{zoom: 1, center: {lat: 0, lng: 0}}}
|
mapView={{zoom: 1, center: {lat: 0, lng: 0}}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
var path = require("path");
|
|
||||||
var mkdirp = require("mkdirp");
|
|
||||||
|
|
||||||
|
|
||||||
function genPath(subPath) {
|
|
||||||
subPath = subPath || ".";
|
|
||||||
var buildPath;
|
|
||||||
|
|
||||||
if(process.env.CIRCLECI) {
|
|
||||||
buildPath = path.join("/tmp/artifacts", subPath);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
buildPath = path.join(__dirname, '..', 'build', subPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
return buildPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.path = function(subPath) {
|
|
||||||
var dirPath = genPath(subPath);
|
|
||||||
|
|
||||||
return new Promise(function(resolve, reject) {
|
|
||||||
mkdirp(dirPath, function(err) {
|
|
||||||
if(err) {
|
|
||||||
reject(err);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
resolve(dirPath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.pathSync = function(subPath) {
|
|
||||||
var dirPath = genPath(subPath);
|
|
||||||
mkdirp.sync(dirPath);
|
|
||||||
return dirPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
var config = {};
|
|
||||||
config.testNetwork = process.env.TEST_NETWORK || "localhost";
|
|
||||||
config.port = 9001;
|
|
||||||
config.baseUrl = "http://"+config.testNetwork+":"+config.port;
|
|
||||||
|
|
||||||
module.exports = config;
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
describe("accessibility", function () {
|
|
||||||
require("./skip-links");
|
|
||||||
})
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
var assert = require("assert");
|
|
||||||
var config = require("../../config/specs");
|
|
||||||
var helper = require("../helper");
|
|
||||||
var wd = require("../../wd-helper");
|
|
||||||
|
|
||||||
|
|
||||||
describe("skip links", function() {
|
|
||||||
beforeEach(async function () {
|
|
||||||
await browser.url(config.baseUrl+"?debug&style="+helper.getGeoServerUrl("example-layer-style.json"));
|
|
||||||
await browser.acceptAlert();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("skip link to layer list", async function() {
|
|
||||||
const selector = wd.$("root:skip:layer-list")
|
|
||||||
const elem = await $(selector);
|
|
||||||
assert(await elem.isExisting());
|
|
||||||
await browser.keys(['Tab']);
|
|
||||||
assert(await elem.isFocused());
|
|
||||||
await elem.click();
|
|
||||||
|
|
||||||
const targetEl = await $("#skip-target-layer-list");
|
|
||||||
assert(await targetEl.isFocused());
|
|
||||||
});
|
|
||||||
|
|
||||||
it("skip link to layer editor", async function() {
|
|
||||||
const selector = wd.$("root:skip:layer-editor")
|
|
||||||
const elem = await $(selector);
|
|
||||||
assert(await elem.isExisting());
|
|
||||||
await browser.keys(['Tab']);
|
|
||||||
await browser.keys(['Tab']);
|
|
||||||
assert(await elem.isFocused());
|
|
||||||
await elem.click();
|
|
||||||
|
|
||||||
const targetEl = await $("#skip-target-layer-editor");
|
|
||||||
assert(await targetEl.isFocused());
|
|
||||||
});
|
|
||||||
|
|
||||||
it("skip link to map view", async function() {
|
|
||||||
const selector = wd.$("root:skip:map-view")
|
|
||||||
const elem = await $(selector);
|
|
||||||
assert(await elem.isExisting());
|
|
||||||
await browser.keys(['Tab']);
|
|
||||||
await browser.keys(['Tab']);
|
|
||||||
await browser.keys(['Tab']);
|
|
||||||
assert(await elem.isFocused());
|
|
||||||
await elem.click();
|
|
||||||
|
|
||||||
const targetEl = await $(".mapboxgl-canvas");
|
|
||||||
assert(await targetEl.isFocused());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
var wd = require("../wd-helper");
|
|
||||||
var {v1: uuid} = require('uuid');
|
|
||||||
var geoServer = require("../geojson-server");
|
|
||||||
|
|
||||||
var testNetwork = process.env.TEST_NETWORK || "localhost";
|
|
||||||
var geoserver;
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
startGeoserver: function(done) {
|
|
||||||
geoserver = geoServer.listen(9002, "0.0.0.0", done);
|
|
||||||
},
|
|
||||||
stopGeoserver: function(done) {
|
|
||||||
geoserver.close(done);
|
|
||||||
geoserver = undefined;
|
|
||||||
},
|
|
||||||
getStyleUrl: function(styles) {
|
|
||||||
var port = geoserver.address().port;
|
|
||||||
return "http://"+testNetwork+":"+port+"/styles/empty/"+styles.join(",");
|
|
||||||
},
|
|
||||||
getGeoServerUrl: function(urlPath) {
|
|
||||||
var port = geoserver.address().port;
|
|
||||||
return "http://"+testNetwork+":"+port+"/"+urlPath;
|
|
||||||
},
|
|
||||||
getStyleStore: async function(browser) {
|
|
||||||
return await browser.executeAsync(function(done) {
|
|
||||||
window.debug.get("maputnik", "styleStore").latestStyle(done);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getRevisionStore: async function(browser) {
|
|
||||||
var result = await browser.execute(function() {
|
|
||||||
var rs = window.debug.get("maputnik", "revisionStore")
|
|
||||||
|
|
||||||
return {
|
|
||||||
currentIdx: rs.currentIdx,
|
|
||||||
revisions: rs.revisions
|
|
||||||
};
|
|
||||||
})
|
|
||||||
return result.value;
|
|
||||||
},
|
|
||||||
modal: {
|
|
||||||
addLayer: {
|
|
||||||
open: async function() {
|
|
||||||
const selector = await $(wd.$('layer-list:add-layer'));
|
|
||||||
await selector.click();
|
|
||||||
|
|
||||||
// Wait for events
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
const elem = await $(wd.$('modal:add-layer'));
|
|
||||||
await elem.waitForExist();
|
|
||||||
await elem.isDisplayed();
|
|
||||||
await elem.isDisplayedInViewport();
|
|
||||||
|
|
||||||
// Wait for events
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
},
|
|
||||||
fill: async function(opts) {
|
|
||||||
var type = opts.type;
|
|
||||||
var layer = opts.layer;
|
|
||||||
var id;
|
|
||||||
if(opts.id) {
|
|
||||||
id = opts.id
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
id = type+":"+uuid();
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectBox = await $(wd.$("add-layer.layer-type", "select"));
|
|
||||||
await selectBox.selectByAttribute('value', type);
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
await browser.setValueSafe(wd.$("add-layer.layer-id", "input"), id);
|
|
||||||
if(layer) {
|
|
||||||
await browser.setValueSafe(wd.$("add-layer.layer-source-block", "input"), layer);
|
|
||||||
}
|
|
||||||
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
const elem_addLayer = await $(wd.$("add-layer"));
|
|
||||||
await elem_addLayer.click();
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
var assert = require("assert");
|
|
||||||
var config = require("../../config/specs");
|
|
||||||
var helper = require("../helper");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
describe("history", function() {
|
|
||||||
let undoKeyCombo;
|
|
||||||
let undoKeyComboReset;
|
|
||||||
let redoKeyCombo;
|
|
||||||
let redoKeyComboReset;
|
|
||||||
|
|
||||||
before(async function() {
|
|
||||||
const isMac = await browser.execute(function() {
|
|
||||||
return navigator.platform.toUpperCase().indexOf('MAC') >= 0;
|
|
||||||
});
|
|
||||||
undoKeyCombo = ['Meta', 'z'];
|
|
||||||
undoKeyComboReset = ['Meta'];
|
|
||||||
redoKeyCombo = isMac ? ['Meta', 'Shift', 'z'] : ['Meta', 'y'];
|
|
||||||
redoKeyComboReset = isMac ? ['Meta', 'Shift'] : ['Meta'];
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* See <https://github.com/webdriverio/webdriverio/issues/1126>
|
|
||||||
*/
|
|
||||||
it.skip("undo/redo", async function() {
|
|
||||||
var styleObj;
|
|
||||||
|
|
||||||
await browser.url(config.baseUrl+"?debug&style="+helper.getStyleUrl([
|
|
||||||
"geojson:example"
|
|
||||||
]));
|
|
||||||
await browser.acceptAlert();
|
|
||||||
|
|
||||||
await helper.modal.addLayer.open();
|
|
||||||
|
|
||||||
styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, []);
|
|
||||||
|
|
||||||
await helper.modal.addLayer.fill({
|
|
||||||
id: "step 1",
|
|
||||||
type: "background"
|
|
||||||
})
|
|
||||||
|
|
||||||
styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": "step 1",
|
|
||||||
"type": 'background'
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
await helper.modal.addLayer.open();
|
|
||||||
await helper.modal.addLayer.fill({
|
|
||||||
id: "step 2",
|
|
||||||
type: "background"
|
|
||||||
})
|
|
||||||
|
|
||||||
styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": "step 1",
|
|
||||||
"type": 'background'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step 2",
|
|
||||||
"type": 'background'
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
await browser.keys(undoKeyCombo)
|
|
||||||
await browser.keys(undoKeyComboReset);
|
|
||||||
styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": "step 1",
|
|
||||||
"type": 'background'
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
await browser.keys(undoKeyCombo)
|
|
||||||
await browser.keys(undoKeyComboReset);
|
|
||||||
styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
]);
|
|
||||||
|
|
||||||
await browser.keys(redoKeyCombo)
|
|
||||||
await browser.keys(redoKeyComboReset);
|
|
||||||
styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": "step 1",
|
|
||||||
"type": 'background'
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
await browser.keys(redoKeyCombo)
|
|
||||||
await browser.keys(redoKeyComboReset);
|
|
||||||
styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": "step 1",
|
|
||||||
"type": 'background'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "step 2",
|
|
||||||
"type": 'background'
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
})
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
var config = require("../config/specs");
|
|
||||||
var helper = require("./helper");
|
|
||||||
var extendWebdriverIO = require("./util/webdriverio-ext");
|
|
||||||
|
|
||||||
|
|
||||||
describe('maputnik', function() {
|
|
||||||
|
|
||||||
before(async function(done) {
|
|
||||||
await extendWebdriverIO();
|
|
||||||
helper.startGeoserver(done);
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function(done) {
|
|
||||||
helper.stopGeoserver(done);
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(async function() {
|
|
||||||
await browser.url(config.baseUrl+"?debug&style="+helper.getStyleUrl([
|
|
||||||
"geojson:example",
|
|
||||||
"raster:raster"
|
|
||||||
]));
|
|
||||||
await browser.acceptAlert();
|
|
||||||
await browser.execute(function() {
|
|
||||||
localStorage.setItem("survey", true);
|
|
||||||
});
|
|
||||||
const elem = await $(".maputnik-toolbar-link");
|
|
||||||
await elem.waitForExist();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
});
|
|
||||||
|
|
||||||
// -------- setup --------
|
|
||||||
require("./util/coverage");
|
|
||||||
// -----------------------
|
|
||||||
|
|
||||||
// ---- All the tests ----
|
|
||||||
require("./history");
|
|
||||||
require("./layers");
|
|
||||||
require("./map");
|
|
||||||
require("./modals");
|
|
||||||
require("./screenshots");
|
|
||||||
require("./accessibility");
|
|
||||||
require("./keyboard");
|
|
||||||
// ------------------------
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
var assert = require("assert");
|
|
||||||
var wd = require("../../wd-helper");
|
|
||||||
|
|
||||||
|
|
||||||
describe("keyboard", function() {
|
|
||||||
describe("shortcuts", function() {
|
|
||||||
it("ESC should unfocus", async function() {
|
|
||||||
const tmpTargetEl = await $(wd.$("nav:inspect") + " select");
|
|
||||||
await tmpTargetEl.click();
|
|
||||||
assert(await tmpTargetEl.isFocused());
|
|
||||||
|
|
||||||
await browser.keys(["Escape"]);
|
|
||||||
assert(await (await $("body")).isFocused());
|
|
||||||
});
|
|
||||||
|
|
||||||
it("'?' should show shortcuts modal", async function() {
|
|
||||||
await browser.keys(["?"]);
|
|
||||||
assert(await (await $(wd.$("modal:shortcuts"))).isDisplayed());
|
|
||||||
});
|
|
||||||
|
|
||||||
it("'o' should show open modal", async function() {
|
|
||||||
await browser.keys(["o"]);
|
|
||||||
assert(await (await $(wd.$("modal:open"))).isDisplayed());
|
|
||||||
});
|
|
||||||
|
|
||||||
it("'e' should show export modal", async function() {
|
|
||||||
await browser.keys(["e"]);
|
|
||||||
assert(await (await $(wd.$("modal:export"))).isDisplayed());
|
|
||||||
});
|
|
||||||
|
|
||||||
it("'d' should show sources modal", async function() {
|
|
||||||
await browser.keys(["d"]);
|
|
||||||
assert(await (await $(wd.$("modal:sources"))).isDisplayed());
|
|
||||||
});
|
|
||||||
|
|
||||||
it("'s' should show settings modal", async function() {
|
|
||||||
await browser.keys(["s"]);
|
|
||||||
assert(await (await $(wd.$("modal:settings"))).isDisplayed());
|
|
||||||
});
|
|
||||||
|
|
||||||
it.skip("'i' should change map to inspect mode", async function() {
|
|
||||||
// await browser.keys(["i"]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("'m' should focus map", async function() {
|
|
||||||
await browser.keys(["m"]);
|
|
||||||
assert(await (await $(".mapboxgl-canvas")).isFocused());
|
|
||||||
});
|
|
||||||
|
|
||||||
it("'!' should show debug modal", async function() {
|
|
||||||
await browser.keys(["!"]);
|
|
||||||
assert(await (await $(wd.$("modal:debug"))).isDisplayed());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,488 +0,0 @@
|
|||||||
var assert = require("assert");
|
|
||||||
var config = require("../../config/specs");
|
|
||||||
var helper = require("../helper");
|
|
||||||
var {v1: uuid} = require('uuid');
|
|
||||||
var wd = require("../../wd-helper");
|
|
||||||
|
|
||||||
|
|
||||||
describe("layers", function() {
|
|
||||||
beforeEach(async function() {
|
|
||||||
await browser.url(config.baseUrl+"?debug&style="+helper.getStyleUrl([
|
|
||||||
"geojson:example",
|
|
||||||
"raster:raster"
|
|
||||||
]));
|
|
||||||
await browser.acceptAlert();
|
|
||||||
const elem = await $(".maputnik-toolbar-link");
|
|
||||||
await elem.waitForExist();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
await helper.modal.addLayer.open();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("ops", function() {
|
|
||||||
it("delete", async function() {
|
|
||||||
var styleObj;
|
|
||||||
var id = await helper.modal.addLayer.fill({
|
|
||||||
type: "background"
|
|
||||||
})
|
|
||||||
|
|
||||||
styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": id,
|
|
||||||
"type": 'background'
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const elem = await $(wd.$("layer-list-item:"+id+":delete", ""));
|
|
||||||
await elem.click();
|
|
||||||
|
|
||||||
styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("duplicate", async function() {
|
|
||||||
var styleObj;
|
|
||||||
var id = await helper.modal.addLayer.fill({
|
|
||||||
type: "background"
|
|
||||||
})
|
|
||||||
|
|
||||||
styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": id,
|
|
||||||
"type": 'background'
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const elem = await $(wd.$("layer-list-item:"+id+":copy", ""));
|
|
||||||
await elem.click();
|
|
||||||
|
|
||||||
styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": id+"-copy",
|
|
||||||
"type": "background"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": id,
|
|
||||||
"type": "background"
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("hide", async function() {
|
|
||||||
var styleObj;
|
|
||||||
var id = await helper.modal.addLayer.fill({
|
|
||||||
type: "background"
|
|
||||||
})
|
|
||||||
|
|
||||||
styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": id,
|
|
||||||
"type": 'background'
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const elem = await $(wd.$("layer-list-item:"+id+":toggle-visibility", ""));
|
|
||||||
await elem.click();
|
|
||||||
|
|
||||||
styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": id,
|
|
||||||
"type": "background",
|
|
||||||
"layout": {
|
|
||||||
"visibility": "none"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
await elem.click();
|
|
||||||
|
|
||||||
styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": id,
|
|
||||||
"type": "background",
|
|
||||||
"layout": {
|
|
||||||
"visibility": "visible"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("tooltips", function() {
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("help", function() {
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
describe('background', function () {
|
|
||||||
|
|
||||||
it("add", async function() {
|
|
||||||
var id = await helper.modal.addLayer.fill({
|
|
||||||
type: "background"
|
|
||||||
})
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": id,
|
|
||||||
"type": 'background'
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("modify", function() {
|
|
||||||
async function createBackground() {
|
|
||||||
// Setup
|
|
||||||
var id = uuid();
|
|
||||||
|
|
||||||
const selectBox = await $(wd.$("add-layer.layer-type", "select"));
|
|
||||||
await selectBox.selectByAttribute('value', "background");
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
await browser.setValueSafe(wd.$("add-layer.layer-id", "input"), "background:"+id);
|
|
||||||
|
|
||||||
const elem = await $(wd.$("add-layer"));
|
|
||||||
await elem.click();
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": 'background:'+id,
|
|
||||||
"type": 'background'
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ====> THESE SHOULD BE FROM THE SPEC
|
|
||||||
describe("layer", function() {
|
|
||||||
it("expand/collapse");
|
|
||||||
it("id", async function() {
|
|
||||||
var bgId = await createBackground();
|
|
||||||
|
|
||||||
const elem = await $(wd.$("layer-list-item:background:"+bgId));
|
|
||||||
await elem.click();
|
|
||||||
|
|
||||||
var id = uuid();
|
|
||||||
await browser.setValueSafe(wd.$("layer-editor.layer-id", "input"), "foobar:"+id)
|
|
||||||
const elem2 = await $(wd.$("min-zoom"));
|
|
||||||
await elem2.click();
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": 'foobar:'+id,
|
|
||||||
"type": 'background'
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("min-zoom", async function() {
|
|
||||||
var bgId = await createBackground();
|
|
||||||
|
|
||||||
const elem = await $(wd.$("layer-list-item:background:"+bgId));
|
|
||||||
await elem.click();
|
|
||||||
await browser.setValueSafe(wd.$("min-zoom", 'input[type="text"]'), 1)
|
|
||||||
const elem2 = await $(wd.$("layer-editor.layer-id", "input"));
|
|
||||||
await elem2.click();
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": 'background:'+bgId,
|
|
||||||
"type": 'background',
|
|
||||||
"minzoom": 1
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
// AND RESET!
|
|
||||||
// await browser.setValueSafe(wd.$("min-zoom", "input"), "")
|
|
||||||
// await browser.click(wd.$("max-zoom", "input"));
|
|
||||||
|
|
||||||
// var styleObj = await helper.getStyleStore(browser);
|
|
||||||
|
|
||||||
// assert.deepEqual(styleObj.layers, [
|
|
||||||
// {
|
|
||||||
// "id": 'background:'+bgId,
|
|
||||||
// "type": 'background'
|
|
||||||
// }
|
|
||||||
// ]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("max-zoom", async function() {
|
|
||||||
var bgId = await createBackground();
|
|
||||||
|
|
||||||
const elem = await $(wd.$("layer-list-item:background:"+bgId));
|
|
||||||
await elem.click();
|
|
||||||
await browser.setValueSafe(wd.$("max-zoom", 'input[type="text"]'), 1)
|
|
||||||
const elem2 = await $(wd.$("layer-editor.layer-id", "input"));
|
|
||||||
await elem2.click();
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": 'background:'+bgId,
|
|
||||||
"type": 'background',
|
|
||||||
"maxzoom": 1
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("comments", async function() {
|
|
||||||
var bgId = await createBackground();
|
|
||||||
var id = uuid();
|
|
||||||
|
|
||||||
const elem = await $(wd.$("layer-list-item:background:"+bgId));
|
|
||||||
await elem.click();
|
|
||||||
await browser.setValueSafe(wd.$("layer-comment", "textarea"), id);
|
|
||||||
const elem2 = await $(wd.$("layer-editor.layer-id", "input"));
|
|
||||||
await elem2.click();
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": 'background:'+bgId,
|
|
||||||
"type": 'background',
|
|
||||||
metadata: {
|
|
||||||
'maputnik:comment': id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Unset it again.
|
|
||||||
// TODO: This fails
|
|
||||||
// await browser.setValueSafe(wd.$("layer-comment", "textarea"), "");
|
|
||||||
// await browser.click(wd.$("min-zoom", "input"));
|
|
||||||
// await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
// var styleObj = await helper.getStyleStore(browser);
|
|
||||||
// assert.deepEqual(styleObj.layers, [
|
|
||||||
// {
|
|
||||||
// "id": 'background:'+bgId,
|
|
||||||
// "type": 'background'
|
|
||||||
// }
|
|
||||||
// ]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("color", null, async function() {
|
|
||||||
var bgId = await createBackground();
|
|
||||||
|
|
||||||
await browser.click(wd.$("layer-list-item:background:"+bgId));
|
|
||||||
|
|
||||||
await browser.click(wd.$("spec-field:background-color", "input"))
|
|
||||||
// await browser.debug();
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": 'background:'+bgId,
|
|
||||||
"type": 'background'
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("filter", function() {
|
|
||||||
it("expand/collapse");
|
|
||||||
it("compound filter");
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("paint", function() {
|
|
||||||
it("expand/collapse");
|
|
||||||
it("color");
|
|
||||||
it("pattern");
|
|
||||||
it("opacity");
|
|
||||||
})
|
|
||||||
// <=====
|
|
||||||
|
|
||||||
describe("json-editor", function() {
|
|
||||||
it("expand/collapse");
|
|
||||||
it("modify");
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
it.skip("parse error", async function() {
|
|
||||||
var bgId = await createBackground();
|
|
||||||
|
|
||||||
await browser.click(wd.$("layer-list-item:background:"+bgId));
|
|
||||||
|
|
||||||
var errorSelector = ".CodeMirror-lint-marker-error";
|
|
||||||
assert.equal(await browser.isExisting(errorSelector), false);
|
|
||||||
|
|
||||||
await browser.click(".CodeMirror")
|
|
||||||
await browser.keys("\uE013\uE013\uE013\uE013\uE013\uE013\uE013\uE013\uE013\uE013\uE013\uE013 {");
|
|
||||||
await browser.waitForExist(errorSelector)
|
|
||||||
|
|
||||||
await browser.click(wd.$("layer-editor.layer-id"));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('fill', function () {
|
|
||||||
it("add", async function() {
|
|
||||||
// await browser.debug();
|
|
||||||
|
|
||||||
var id = await helper.modal.addLayer.fill({
|
|
||||||
type: "fill",
|
|
||||||
layer: "example"
|
|
||||||
});
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": id,
|
|
||||||
"type": 'fill',
|
|
||||||
"source": "example"
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
})
|
|
||||||
|
|
||||||
// TODO: Change source
|
|
||||||
it("change source")
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('line', function () {
|
|
||||||
it("add", async function() {
|
|
||||||
var id = await helper.modal.addLayer.fill({
|
|
||||||
type: "line",
|
|
||||||
layer: "example"
|
|
||||||
});
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": id,
|
|
||||||
"type": "line",
|
|
||||||
"source": "example",
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("groups", null, function() {
|
|
||||||
// TODO
|
|
||||||
// Click each of the layer groups.
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('symbol', function () {
|
|
||||||
it("add", async function() {
|
|
||||||
var id = await helper.modal.addLayer.fill({
|
|
||||||
type: "symbol",
|
|
||||||
layer: "example"
|
|
||||||
});
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": id,
|
|
||||||
"type": "symbol",
|
|
||||||
"source": "example",
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('raster', function () {
|
|
||||||
it("add", async function() {
|
|
||||||
var id = await helper.modal.addLayer.fill({
|
|
||||||
type: "raster",
|
|
||||||
layer: "raster"
|
|
||||||
});
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": id,
|
|
||||||
"type": "raster",
|
|
||||||
"source": "raster",
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('circle', function () {
|
|
||||||
it("add", async function() {
|
|
||||||
var id = await helper.modal.addLayer.fill({
|
|
||||||
type: "circle",
|
|
||||||
layer: "example"
|
|
||||||
});
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": id,
|
|
||||||
"type": "circle",
|
|
||||||
"source": "example",
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('fill extrusion', function () {
|
|
||||||
it("add", async function() {
|
|
||||||
var id = await helper.modal.addLayer.fill({
|
|
||||||
type: "fill-extrusion",
|
|
||||||
layer: "example"
|
|
||||||
});
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleObj.layers, [
|
|
||||||
{
|
|
||||||
"id": id,
|
|
||||||
"type": 'fill-extrusion',
|
|
||||||
"source": "example"
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
describe("groups", function() {
|
|
||||||
it("simple", async function() {
|
|
||||||
await browser.url(config.baseUrl+"?debug&style="+helper.getStyleUrl([
|
|
||||||
"geojson:example"
|
|
||||||
]));
|
|
||||||
await browser.acceptAlert();
|
|
||||||
|
|
||||||
await helper.modal.addLayer.open();
|
|
||||||
await helper.modal.addLayer.fill({
|
|
||||||
id: "foo",
|
|
||||||
type: "background"
|
|
||||||
})
|
|
||||||
|
|
||||||
await helper.modal.addLayer.open();
|
|
||||||
await helper.modal.addLayer.fill({
|
|
||||||
id: "foo_bar",
|
|
||||||
type: "background"
|
|
||||||
})
|
|
||||||
|
|
||||||
await helper.modal.addLayer.open();
|
|
||||||
await helper.modal.addLayer.fill({
|
|
||||||
id: "foo_bar_baz",
|
|
||||||
type: "background"
|
|
||||||
})
|
|
||||||
|
|
||||||
const groupEl = await $(wd.$("layer-list-group:foo-0"));
|
|
||||||
await groupEl.isDisplayed();
|
|
||||||
|
|
||||||
assert.equal(await (await $(wd.$("layer-list-item:foo"))).isDisplayedInViewport(), true);
|
|
||||||
assert.equal(await (await $(wd.$("layer-list-item:foo_bar"))).isDisplayedInViewport(), false);
|
|
||||||
assert.equal(await (await $(wd.$("layer-list-item:foo_bar_baz"))).isDisplayedInViewport(), false);
|
|
||||||
|
|
||||||
await groupEl.click();
|
|
||||||
|
|
||||||
assert.equal(await (await $(wd.$("layer-list-item:foo"))).isDisplayedInViewport(), true);
|
|
||||||
assert.equal(await (await $(wd.$("layer-list-item:foo_bar"))).isDisplayedInViewport(), true);
|
|
||||||
assert.equal(await (await $(wd.$("layer-list-item:foo_bar_baz"))).isDisplayedInViewport(), true);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
});
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
var config = require("../../config/specs");
|
|
||||||
var helper = require("../helper");
|
|
||||||
|
|
||||||
|
|
||||||
describe("map", function() {
|
|
||||||
describe.skip("zoom level", function() {
|
|
||||||
it("via url", async function() {
|
|
||||||
var zoomLevel = "12.37"
|
|
||||||
await browser.url(config.baseUrl+"?debug&style="+helper.getStyleUrl([
|
|
||||||
"geojson:example"
|
|
||||||
])+"#"+zoomLevel+"/41.3805/2.1635");
|
|
||||||
await browser.alertAccept();
|
|
||||||
|
|
||||||
await browser.waitUntil(async function () {
|
|
||||||
return (
|
|
||||||
await browser.isVisible(".mapboxgl-ctrl-zoom")
|
|
||||||
&& await browser.getText(".mapboxgl-ctrl-zoom") === "Zoom level: "+(zoomLevel)
|
|
||||||
);
|
|
||||||
}, 10*1000)
|
|
||||||
})
|
|
||||||
it("via map controls", async function() {
|
|
||||||
var zoomLevel = 12.37;
|
|
||||||
await browser.url(config.baseUrl+"?debug&style="+helper.getStyleUrl([
|
|
||||||
"geojson:example"
|
|
||||||
])+"#"+zoomLevel+"/41.3805/2.1635");
|
|
||||||
await browser.alertAccept();
|
|
||||||
|
|
||||||
await browser.click(".mapboxgl-ctrl-zoom-in")
|
|
||||||
await browser.waitUntil(async function () {
|
|
||||||
var text = await browser.getText(".mapboxgl-ctrl-zoom")
|
|
||||||
return text === "Zoom level: "+(zoomLevel+1);
|
|
||||||
}, 10*1000)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,237 +0,0 @@
|
|||||||
var assert = require('assert');
|
|
||||||
var fs = require("fs");
|
|
||||||
var wd = require("../../wd-helper");
|
|
||||||
var config = require("../../config/specs");
|
|
||||||
var helper = require("../helper");
|
|
||||||
|
|
||||||
|
|
||||||
async function closeModal(wdKey) {
|
|
||||||
const selector = wd.$(wdKey);
|
|
||||||
|
|
||||||
await browser.waitUntil(async function() {
|
|
||||||
const elem = await $(selector);
|
|
||||||
return await elem.isDisplayedInViewport();
|
|
||||||
});
|
|
||||||
|
|
||||||
const closeBtnSelector = await $(wd.$(wdKey+".close-modal"));
|
|
||||||
await closeBtnSelector.click();
|
|
||||||
|
|
||||||
await browser.waitUntil(async function() {
|
|
||||||
return await browser.execute((selector) => {
|
|
||||||
return !document.querySelector(selector);
|
|
||||||
}, selector);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
describe("modals", function() {
|
|
||||||
describe("open", function() {
|
|
||||||
var styleFilePath = __dirname+"/../../example-style.json";
|
|
||||||
var styleFileData = JSON.parse(fs.readFileSync(styleFilePath));
|
|
||||||
|
|
||||||
beforeEach(async function() {
|
|
||||||
await browser.url(config.baseUrl+"?debug");
|
|
||||||
|
|
||||||
const elem = await $(".maputnik-toolbar-link");
|
|
||||||
await elem.waitForExist();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
const elem2 = await $(wd.$("nav:open"));
|
|
||||||
await elem2.click();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("close", async function() {
|
|
||||||
await closeModal("modal:open");
|
|
||||||
});
|
|
||||||
|
|
||||||
// "chooseFile" command currently not available for wdio v5 https://github.com/webdriverio/webdriverio/pull/3632
|
|
||||||
it.skip("upload", async function() {
|
|
||||||
const elem = await $("*[type='file']");
|
|
||||||
await elem.waitForExist();
|
|
||||||
await browser.chooseFile("*[type='file']", styleFilePath);
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleFileData, styleObj);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("load from url", async function() {
|
|
||||||
var styleFileUrl = helper.getGeoServerUrl("example-style.json");
|
|
||||||
|
|
||||||
await browser.setValueSafe(wd.$("modal:open.url.input"), styleFileUrl);
|
|
||||||
|
|
||||||
const selector = await $(wd.$("modal:open.url.button"));
|
|
||||||
await selector.click();
|
|
||||||
|
|
||||||
// Allow the network request to happen
|
|
||||||
// NOTE: Its localhost so this should be fast.
|
|
||||||
await browser.pause(300);
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.deepEqual(styleFileData, styleObj);
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO: Need to work out how to mock out the end points
|
|
||||||
it("gallery")
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("shortcuts", function() {
|
|
||||||
it("open/close", async function() {
|
|
||||||
await browser.url(config.baseUrl+"?debug");
|
|
||||||
|
|
||||||
const elem = await $(".maputnik-toolbar-link");
|
|
||||||
await elem.waitForExist();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
await browser.keys(["?"]);
|
|
||||||
|
|
||||||
const modalEl = await $(wd.$("modal:shortcuts"))
|
|
||||||
assert(await modalEl.isDisplayed());
|
|
||||||
|
|
||||||
await closeModal("modal:shortcuts");
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("export", function() {
|
|
||||||
|
|
||||||
beforeEach(async function() {
|
|
||||||
await browser.url(config.baseUrl+"?debug");
|
|
||||||
|
|
||||||
const elem = await $(".maputnik-toolbar-link");
|
|
||||||
await elem.waitForExist();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
const elem2 = await $(wd.$("nav:export"));
|
|
||||||
await elem2.click();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("close", async function() {
|
|
||||||
await closeModal("modal:export");
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO: Work out how to download a file and check the contents
|
|
||||||
it("download")
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("sources", function() {
|
|
||||||
it("active sources")
|
|
||||||
it("public source")
|
|
||||||
it("add new source")
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("inspect", function() {
|
|
||||||
it("toggle", async function() {
|
|
||||||
await browser.url(config.baseUrl+"?debug&style="+helper.getStyleUrl([
|
|
||||||
"geojson:example"
|
|
||||||
]));
|
|
||||||
await browser.acceptAlert();
|
|
||||||
|
|
||||||
const selectBox = await $(wd.$("nav:inspect", "select"));
|
|
||||||
await selectBox.selectByAttribute('value', "inspect");
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("style settings", function() {
|
|
||||||
beforeEach(async function() {
|
|
||||||
await browser.url(config.baseUrl+"?debug");
|
|
||||||
|
|
||||||
const elem = await $(".maputnik-toolbar-link");
|
|
||||||
await elem.waitForExist();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
const elem2 = await $(wd.$("nav:settings"));
|
|
||||||
await elem2.click();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("name", async function() {
|
|
||||||
await browser.setValueSafe(wd.$("modal:settings.name"), "foobar")
|
|
||||||
const elem = await $(wd.$("modal:settings.owner"));
|
|
||||||
await elem.click();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.equal(styleObj.name, "foobar");
|
|
||||||
})
|
|
||||||
it("owner", async function() {
|
|
||||||
await browser.setValueSafe(wd.$("modal:settings.owner"), "foobar")
|
|
||||||
const elem = await $(wd.$("modal:settings.name"));
|
|
||||||
await elem.click();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.equal(styleObj.owner, "foobar");
|
|
||||||
})
|
|
||||||
it("sprite url", async function() {
|
|
||||||
await browser.setValueSafe(wd.$("modal:settings.sprite"), "http://example.com")
|
|
||||||
const elem = await $(wd.$("modal:settings.name"));
|
|
||||||
await elem.click();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.equal(styleObj.sprite, "http://example.com");
|
|
||||||
})
|
|
||||||
it("glyphs url", async function() {
|
|
||||||
var glyphsUrl = "http://example.com/{fontstack}/{range}.pbf"
|
|
||||||
await browser.setValueSafe(wd.$("modal:settings.glyphs"), glyphsUrl)
|
|
||||||
const elem = await $(wd.$("modal:settings.name"));
|
|
||||||
await elem.click();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.equal(styleObj.glyphs, glyphsUrl);
|
|
||||||
})
|
|
||||||
|
|
||||||
it("mapbox access token", async function() {
|
|
||||||
var apiKey = "testing123";
|
|
||||||
await browser.setValueSafe(wd.$("modal:settings.maputnik:mapbox_access_token"), apiKey);
|
|
||||||
const elem = await $(wd.$("modal:settings.name"));
|
|
||||||
await elem.click();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
await browser.waitUntil(function() {
|
|
||||||
return styleObj.metadata["maputnik:mapbox_access_token"] == apiKey;
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it("maptiler access token", async function() {
|
|
||||||
var apiKey = "testing123";
|
|
||||||
await browser.setValueSafe(wd.$("modal:settings.maputnik:openmaptiles_access_token"), apiKey);
|
|
||||||
const elem = await $(wd.$("modal:settings.name"));
|
|
||||||
await elem.click();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.equal(styleObj.metadata["maputnik:openmaptiles_access_token"], apiKey);
|
|
||||||
})
|
|
||||||
|
|
||||||
it("thunderforest access token", async function() {
|
|
||||||
var apiKey = "testing123";
|
|
||||||
await browser.setValueSafe(wd.$("modal:settings.maputnik:thunderforest_access_token"), apiKey);
|
|
||||||
const elem = await $(wd.$("modal:settings.name"));
|
|
||||||
await elem.click();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.equal(styleObj.metadata["maputnik:thunderforest_access_token"], apiKey);
|
|
||||||
})
|
|
||||||
|
|
||||||
it("style renderer", async function() {
|
|
||||||
const selector = await $(wd.$("modal:settings.maputnik:renderer"));
|
|
||||||
await selector.selectByAttribute('value', "ol");
|
|
||||||
const elem = await $(wd.$("modal:settings.name"));
|
|
||||||
await elem.click();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
var styleObj = await helper.getStyleStore(browser);
|
|
||||||
assert.equal(styleObj.metadata["maputnik:renderer"], "ol");
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("sources", function() {
|
|
||||||
it("toggle")
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
var config = require("../../config/specs");
|
|
||||||
var helper = require("../helper");
|
|
||||||
var wd = require("../../wd-helper");
|
|
||||||
|
|
||||||
|
|
||||||
// These will get used in the marketing material. They are also useful to do a quick manual check of the styling across browsers
|
|
||||||
// NOTE: These duplicate some of the tests, however this is indended becuase it's likely these will change for aesthetic reasons over time
|
|
||||||
describe('screenshots', function() {
|
|
||||||
|
|
||||||
beforeEach(async function() {
|
|
||||||
await browser.setWindowSize(1280, 800)
|
|
||||||
})
|
|
||||||
|
|
||||||
it("front_page", async function() {
|
|
||||||
await browser.url(config.baseUrl+"?debug&style="+helper.getStyleUrl([
|
|
||||||
"geojson:example"
|
|
||||||
]));
|
|
||||||
await browser.acceptAlert();
|
|
||||||
const elem = await $(".maputnik-toolbar-link");
|
|
||||||
await elem.waitForExist();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
await browser.takeScreenShot("/front_page.png")
|
|
||||||
})
|
|
||||||
|
|
||||||
it("open", async function() {
|
|
||||||
await browser.url(config.baseUrl+"?debug&style="+helper.getStyleUrl([
|
|
||||||
"geojson:example"
|
|
||||||
]));
|
|
||||||
await browser.acceptAlert();
|
|
||||||
const elem = await $(".maputnik-toolbar-link");
|
|
||||||
await elem.waitForExist();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
const nav_open = await $(wd.$("nav:open"));
|
|
||||||
await nav_open.click();
|
|
||||||
await nav_open.waitForExist();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
await browser.takeScreenShot("/open.png")
|
|
||||||
})
|
|
||||||
|
|
||||||
it("export", async function() {
|
|
||||||
await browser.url(config.baseUrl+"?debug&style="+helper.getStyleUrl([
|
|
||||||
"geojson:example"
|
|
||||||
]));
|
|
||||||
await browser.acceptAlert();
|
|
||||||
const elem = await $(".maputnik-toolbar-link")
|
|
||||||
await elem.waitForExist()
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
const nav_export = await $(wd.$("nav:export"));
|
|
||||||
await nav_export.click();
|
|
||||||
await nav_export.waitForExist();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
await browser.takeScreenShot("/export.png")
|
|
||||||
})
|
|
||||||
|
|
||||||
it("sources", async function() {
|
|
||||||
await browser.url(config.baseUrl+"?debug&style="+helper.getStyleUrl([
|
|
||||||
"geojson:example"
|
|
||||||
]));
|
|
||||||
await browser.acceptAlert();
|
|
||||||
const elem = await $(".maputnik-toolbar-link")
|
|
||||||
await elem.waitForExist()
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
const nav_sources = await $(wd.$("nav:sources"));
|
|
||||||
await nav_sources.click();
|
|
||||||
await nav_sources.waitForExist();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
await browser.takeScreenShot("/sources.png")
|
|
||||||
})
|
|
||||||
|
|
||||||
it("style settings", async function() {
|
|
||||||
await browser.url(config.baseUrl+"?debug&style="+helper.getStyleUrl([
|
|
||||||
"geojson:example"
|
|
||||||
]));
|
|
||||||
await browser.acceptAlert();
|
|
||||||
const elem = await $(".maputnik-toolbar-link")
|
|
||||||
await elem.waitForExist()
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
const nav_settings = await $(wd.$("nav:settings"));
|
|
||||||
await nav_settings.click();
|
|
||||||
await nav_settings.waitForExist();
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
await browser.takeScreenShot("/settings.png")
|
|
||||||
})
|
|
||||||
|
|
||||||
it("inspect", async function() {
|
|
||||||
await browser.url(config.baseUrl+"?debug&style="+helper.getStyleUrl([
|
|
||||||
"geojson:example"
|
|
||||||
]));
|
|
||||||
await browser.acceptAlert();
|
|
||||||
const elem = await $(".maputnik-toolbar-link")
|
|
||||||
await elem.waitForExist()
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
const selectBox = await $(wd.$("nav:inspect", "select"));
|
|
||||||
await selectBox.selectByAttribute('value', 'inspect');
|
|
||||||
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
|
|
||||||
await browser.takeScreenShot("/inspect.png")
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
var artifacts = require("../../artifacts");
|
|
||||||
var fs = require("fs");
|
|
||||||
var istanbulCov = require('istanbul-lib-coverage');
|
|
||||||
|
|
||||||
var COVERAGE_PATH = artifacts.pathSync("/coverage");
|
|
||||||
|
|
||||||
|
|
||||||
var coverage = istanbulCov.createCoverageMap({});
|
|
||||||
|
|
||||||
// Capture the coverage after each test
|
|
||||||
afterEach(async function() {
|
|
||||||
// Code coverage
|
|
||||||
var results = await browser.execute(function() {
|
|
||||||
return window.__coverage__;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (results) {
|
|
||||||
coverage.merge(results);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Dump the coverage to a file
|
|
||||||
after(function() {
|
|
||||||
|
|
||||||
// Sometimes istanbul copies same location entry with null values
|
|
||||||
// crashing the final coverage step. This is just a workaround for now,
|
|
||||||
// since istanbul will be replaced by nyc.
|
|
||||||
const coverageJson = JSON.stringify(coverage, null, 2);
|
|
||||||
let newCoverage = JSON.parse(coverageJson);
|
|
||||||
|
|
||||||
Object.values(newCoverage).forEach(fileCov => {
|
|
||||||
if (fileCov.branchMap) {
|
|
||||||
Object.values(fileCov.branchMap).forEach(branchMapEntry => {
|
|
||||||
let prevLocation = {};
|
|
||||||
branchMapEntry.locations.forEach(curLocation => {
|
|
||||||
if (curLocation.start && curLocation.end &&
|
|
||||||
curLocation.start.column && curLocation.start.line &&
|
|
||||||
curLocation.end.column && curLocation.end.line)
|
|
||||||
{
|
|
||||||
prevLocation = curLocation;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
curLocation.start.column = prevLocation.start.column;
|
|
||||||
curLocation.start.line = prevLocation.start.line;
|
|
||||||
curLocation.end.column = prevLocation.end.column;
|
|
||||||
curLocation.end.line = prevLocation.end.line;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const newCoverageJson = JSON.stringify(newCoverage, null, 2);
|
|
||||||
fs.writeFileSync(COVERAGE_PATH+"/coverage.json", newCoverageJson);
|
|
||||||
})
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
var artifacts = require("../../artifacts");
|
|
||||||
var path = require("path");
|
|
||||||
|
|
||||||
const extendWebdriverIO = async function() {
|
|
||||||
await browser.setTimeout({ 'script': 20 * 1000 });
|
|
||||||
await browser.setTimeout({ 'implicit': 20 * 1000 });
|
|
||||||
|
|
||||||
var SCREENSHOTS_PATH = artifacts.pathSync("/screenshots");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sometimes chrome driver can result in the wrong text.
|
|
||||||
*
|
|
||||||
* See <https://github.com/webdriverio/webdriverio/issues/1886>
|
|
||||||
*/
|
|
||||||
try {
|
|
||||||
await browser.addCommand('setValueSafe', async function (selector, text) {
|
|
||||||
for (var i = 0; i < 10; i++) {
|
|
||||||
const elem = await $(selector);
|
|
||||||
await elem.waitForDisplayed(500);
|
|
||||||
|
|
||||||
var elements = await browser.findElements("css selector", selector);
|
|
||||||
if (elements.length > 1) {
|
|
||||||
throw "Too many elements found";
|
|
||||||
}
|
|
||||||
|
|
||||||
const elem2 = await $(selector);
|
|
||||||
await elem2.setValue(text);
|
|
||||||
|
|
||||||
var browserText = await elem2.getValue();
|
|
||||||
|
|
||||||
if (browserText == text) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.error("Warning: setValue failed, trying again");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for change events to fire and state updated
|
|
||||||
await browser.flushReactUpdates();
|
|
||||||
})
|
|
||||||
|
|
||||||
await browser.addCommand('takeScreenShot', async function (filepath) {
|
|
||||||
var savepath = path.join(SCREENSHOTS_PATH, filepath);
|
|
||||||
await browser.saveScreenshot(savepath);
|
|
||||||
});
|
|
||||||
|
|
||||||
await browser.addCommand('flushReactUpdates', async function () {
|
|
||||||
await browser.executeAsync(function (done) {
|
|
||||||
// For any events to propagate
|
|
||||||
setTimeout(function () {
|
|
||||||
// For the DOM to be updated.
|
|
||||||
setTimeout(done, 0);
|
|
||||||
}, 0)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
console.error(">>> Ignored error: " + err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = extendWebdriverIO;
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
const cors = require("cors");
|
|
||||||
const express = require("express");
|
|
||||||
const fs = require("fs");
|
|
||||||
const sourceData = require("./sources");
|
|
||||||
|
|
||||||
|
|
||||||
var app = express();
|
|
||||||
|
|
||||||
app.use(cors());
|
|
||||||
|
|
||||||
|
|
||||||
function buildStyle(opts) {
|
|
||||||
opts = opts || {};
|
|
||||||
opts = Object.assign({
|
|
||||||
sources: {}
|
|
||||||
}, opts);
|
|
||||||
|
|
||||||
return {
|
|
||||||
"id": "test-style",
|
|
||||||
"version": 8,
|
|
||||||
"name": "Test Style",
|
|
||||||
"metadata": {
|
|
||||||
"maputnik:renderer": "mbgljs"
|
|
||||||
},
|
|
||||||
"sources": opts.sources,
|
|
||||||
"glyphs": "https://example.local/fonts/{fontstack}/{range}.pbf",
|
|
||||||
"sprites": "https://example.local/fonts/{fontstack}/{range}.pbf",
|
|
||||||
"layers": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildGeoJSONSource(data) {
|
|
||||||
return {
|
|
||||||
type: "vector",
|
|
||||||
data: data
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildResterSource(req, key) {
|
|
||||||
return {
|
|
||||||
"tileSize": 256,
|
|
||||||
"tiles": [
|
|
||||||
req.protocol + '://' + req.get('host') + "/" + key + "/{x}/{y}/{z}"
|
|
||||||
],
|
|
||||||
"type": "raster"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
app.get("/sources/raster/{x}/{y}/{z}", function(req, res) {
|
|
||||||
res.status(404).end();
|
|
||||||
})
|
|
||||||
|
|
||||||
app.get("/styles/empty/:sources", function(req, res) {
|
|
||||||
var reqSources = req.params.sources.split(",");
|
|
||||||
|
|
||||||
var sources = {};
|
|
||||||
reqSources.forEach(function(key) {
|
|
||||||
var parts = key.split(":");
|
|
||||||
var type = parts[0];
|
|
||||||
var key = parts[1];
|
|
||||||
|
|
||||||
if(type === "geojson") {
|
|
||||||
sources[key] = buildGeoJSONSource(sourceData[key]);
|
|
||||||
}
|
|
||||||
else if(type === "raster") {
|
|
||||||
sources[key] = buildResterSource(req, key);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.error("ERR: Invalid type: %s", type);
|
|
||||||
throw "Invalid type"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var json = buildStyle({
|
|
||||||
sources: sources
|
|
||||||
});
|
|
||||||
res.send(json);
|
|
||||||
})
|
|
||||||
|
|
||||||
app.get("/example-layer-style.json", function(req, res) {
|
|
||||||
res.json(
|
|
||||||
JSON.parse(
|
|
||||||
fs.readFileSync(__dirname+"/example-layer-style.json").toString()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
})
|
|
||||||
|
|
||||||
app.get("/example-style.json", function(req, res) {
|
|
||||||
res.json(
|
|
||||||
JSON.parse(
|
|
||||||
fs.readFileSync(__dirname+"/example-style.json").toString()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = app;
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"type":"FeatureCollection",
|
|
||||||
"features":[
|
|
||||||
{
|
|
||||||
"type":"Feature",
|
|
||||||
"properties": {
|
|
||||||
"name": "Dinagat Islands"
|
|
||||||
},
|
|
||||||
"geometry":{
|
|
||||||
"type": "Point",
|
|
||||||
"coordinates": [125.6, 10.1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
example: require("./example")
|
|
||||||
};
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
"$": function(key, selector) {
|
|
||||||
selector = selector || "";
|
|
||||||
return "*[data-wd-key='"+key+"'] "+selector;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+103
@@ -0,0 +1,103 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
/* Visit https://aka.ms/tsconfig to read more about this file */
|
||||||
|
|
||||||
|
/* Projects */
|
||||||
|
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
|
||||||
|
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||||
|
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
|
||||||
|
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
||||||
|
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||||
|
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||||
|
|
||||||
|
/* Language and Environment */
|
||||||
|
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||||
|
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||||
|
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
||||||
|
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
|
||||||
|
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||||
|
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
||||||
|
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||||
|
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
||||||
|
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
|
||||||
|
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||||
|
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||||
|
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
||||||
|
|
||||||
|
/* Modules */
|
||||||
|
"module": "commonjs", /* Specify what module code is generated. */
|
||||||
|
// "rootDir": "./", /* Specify the root folder within your source files. */
|
||||||
|
// "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||||
|
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||||
|
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||||
|
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||||
|
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
|
||||||
|
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||||
|
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||||
|
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
||||||
|
"resolveJsonModule": true, /* Enable importing .json files. */
|
||||||
|
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
|
||||||
|
|
||||||
|
/* JavaScript Support */
|
||||||
|
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
||||||
|
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||||
|
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
||||||
|
|
||||||
|
/* Emit */
|
||||||
|
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||||
|
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||||
|
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||||
|
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||||
|
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
||||||
|
// "outDir": "./", /* Specify an output folder for all emitted files. */
|
||||||
|
// "removeComments": true, /* Disable emitting comments. */
|
||||||
|
"noEmit": true, /* Disable emitting files from a compilation. */
|
||||||
|
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||||
|
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
|
||||||
|
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||||
|
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
||||||
|
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||||
|
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||||
|
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
||||||
|
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
||||||
|
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
||||||
|
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
|
||||||
|
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
|
||||||
|
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
||||||
|
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
|
||||||
|
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||||
|
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
||||||
|
|
||||||
|
/* Interop Constraints */
|
||||||
|
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||||
|
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
||||||
|
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
|
||||||
|
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||||
|
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
||||||
|
|
||||||
|
/* Type Checking */
|
||||||
|
"strict": true, /* Enable all strict type-checking options. */
|
||||||
|
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
|
||||||
|
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
|
||||||
|
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||||
|
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
|
||||||
|
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||||
|
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
|
||||||
|
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
||||||
|
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
||||||
|
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
|
||||||
|
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
|
||||||
|
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||||
|
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||||
|
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||||
|
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
|
||||||
|
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||||
|
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
|
||||||
|
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||||
|
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||||
|
|
||||||
|
/* Completeness */
|
||||||
|
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||||
|
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user