Skip to content

Commit

Permalink
feat(config-cli): New config-cli package includes dump basemaps scree…
Browse files Browse the repository at this point in the history
…nshots command line tool (#2231)

* New config-cli package include dump basemaps screenshots

* Convert the test tiles into json file.

* Remove unused imports

* Move bmc into bin file

* Remove verbose as it is handdled by Basecommandline

* Using Zod to parse test tiles

* Update yarn.locl

* Some minor changes.
  • Loading branch information
Wentao-Kuang committed Jun 2, 2022
1 parent e7b6a9e commit 39186d5
Show file tree
Hide file tree
Showing 9 changed files with 293 additions and 0 deletions.
18 changes: 18 additions & 0 deletions packages/config-cli/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Basemaps Config CLI

This package is to control the configuration in the LINZ basemaps product.

## Usage -- Screenshots

Dump the screenshots from basemaps production

```bash
./bin/bmc.js screenshot
```

Dump the screenshots from different host and tag

```bash
./bin/bmc.js screenshot --host HOST --tag PR-TAG

```
5 changes: 5 additions & 0 deletions packages/config-cli/bin/bmc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env node
Error.stackTraceLimit = 100;
import { BasemapsConfig } from '../build/cli/screenshot/index.js';

new BasemapsConfig().run();
42 changes: 42 additions & 0 deletions packages/config-cli/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "@basemaps/config-cli",
"version": "6.27.0",
"repository": {
"type": "git",
"url": "https://github.com/linz/basemaps.git",
"directory": "packages/config"
},
"author": {
"name": "Land Information New Zealand",
"url": "https://linz.govt.nz",
"organization": true
},
"type": "module",
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"license": "MIT",
"main": "./build/index.js",
"types": "./build/index.d.ts",
"bin": {
"bmc": "./bin/bmc.js"
},
"scripts": {
"test": "ospec --globs 'build/**/*.test.js'"
},
"publishConfig": {
"access": "public"
},
"files": [
"build/",
"bin/"
],
"dependencies": {
"@basemaps/config-cli": "^6.27.0",
"@basemaps/geo": "^6.26.0",
"@basemaps/shared": "^6.27.0",
"@rushstack/ts-command-line": "^4.3.13",
"playwright": "^1.22.0",
"zod": "^3.17.3"
}
}
13 changes: 13 additions & 0 deletions packages/config-cli/src/cli/screenshot/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { BaseCommandLine } from '@basemaps/shared/build/cli/base.js';
import 'source-map-support/register.js';
import { CommandScreenShot } from './screenshot.js';

export class BasemapsConfig extends BaseCommandLine {
constructor() {
super({
toolFilename: 'bmc',
toolDescription: 'Basemaps config command tools',
});
this.addAction(new CommandScreenShot());
}
}
142 changes: 142 additions & 0 deletions packages/config-cli/src/cli/screenshot/screenshot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import { Config, fsa, LogConfig, LogType } from '@basemaps/shared';
import { mkdir } from 'fs/promises';
import { Browser, chromium } from 'playwright';
import { CommandLineAction, CommandLineStringParameter } from '@rushstack/ts-command-line';
import { z } from 'zod';

enum TileMatrixIdentifier {
Nztm2000Quad = 'NZTM2000Quad',
Google = 'WebMercatorQuad',
}

const zLocation = z.object({
lat: z.number().gte(-90).lte(90),
lng: z.number().gte(-180).lte(180),
z: z.number().gte(0).lte(32),
});

const zTileTest = z.object({
name: z.string(),
tileMatrix: z.nativeEnum(TileMatrixIdentifier),
location: zLocation,
tileSet: z.string(),
style: z.string().optional(),
});

export type TileTestSchema = z.infer<typeof zTileTest>;

export class CommandScreenShot extends CommandLineAction {
private host: CommandLineStringParameter;
private tag: CommandLineStringParameter;
private tiles: CommandLineStringParameter;

public constructor() {
super({
actionName: 'screenshot',
summary: 'dump screenshots of from LINZ Basemaps',
documentation: 'Dump screenshots with selected tile sets',
});
}

protected onDefineParameters(): void {
this.host = this.defineStringParameter({
argumentName: 'HOST',
parameterLongName: '--host',
description: 'Host to use',
defaultValue: 'basemaps.linz.govt.nz',
});

this.tag = this.defineStringParameter({
argumentName: 'TAG',
parameterShortName: '-t',
parameterLongName: '--tag',
description: 'PR tag(PR-number) or "production"',
defaultValue: 'production',
});

this.tiles = this.defineStringParameter({
argumentName: 'TILES',
parameterLongName: '--tiles',
description: 'JSON file path for the test tiles',
defaultValue: './test-tiles/default.test.tiles.json',
});
}

async onExecute(): Promise<void> {
const logger = LogConfig.get();
logger.info('Page:Launch');
const chrome = await chromium.launch();

try {
await this.takeScreenshots(chrome, logger);
} finally {
await chrome.close();
}
}

async takeScreenshots(chrome: Browser, logger: LogType): Promise<void> {
const host = this.host.value ?? this.host.defaultValue;
const tag = this.tag.value ?? this.tag.defaultValue;
const tiles = this.tiles.value ?? this.tiles.defaultValue;
if (host == null || tag == null || tiles == null)
throw new Error('Missing essential parameter to run the process.');

const TestTiles = await fsa.readJson<TileTestSchema[]>(tiles);
for (const test of TestTiles) {
const page = await chrome.newPage();

const tileSetId = await this.getTileSetId(test.tileSet, tag);
const styleId = await this.getStyleId(test.style, tag);

const searchParam = new URLSearchParams();
searchParam.set('p', test.tileMatrix);
searchParam.set('i', tileSetId);
if (styleId) searchParam.set('s', styleId);

const loc = `@${test.location.lat},${test.location.lng},z${test.location.z}`;
const fileName = '.artifacts/visual-snapshots/' + host + '_' + test.name + '.png';

await mkdir(`.artifacts/visual-snapshots/`, { recursive: true });

const url = `https://${host}/?${searchParam.toString()}&debug=true&debug.screenshot=true#${loc}`;

logger.info({ url, expected: fileName }, 'Page:Load');

await page.goto(url);

try {
await page.waitForSelector('div#map-loaded', { state: 'attached' });
await page.waitForTimeout(1000);
await page.waitForLoadState('networkidle');
await page.screenshot({ path: fileName });
} catch (e) {
await page.screenshot({ path: fileName });
throw e;
}
logger.info({ url, expected: fileName }, 'Page:Load:Done');
await page.close();
}
}

async getTileSetId(tileSetId: string, tag: string): Promise<string> {
if (tag === 'production') return tileSetId;

const tileSetTagId = `${tileSetId}@${tag}`;
const dbId = Config.TileSet.id(tileSetTagId);
const tileSet = await Config.TileSet.get(dbId);

if (tileSet) return tileSetTagId;
return tileSetId;
}

async getStyleId(styleId: string | undefined, tag: string): Promise<string> {
if (styleId == null) return '';
if (tag === 'production') return styleId ?? '';

const styleIdTagId = `${styleId}@${tag}`;
const dbId = Config.Style.id(styleIdTagId);
const style = await Config.Style.get(dbId);
if (style) return styleIdTagId;
return styleId;
}
}
42 changes: 42 additions & 0 deletions packages/config-cli/test-tiles/default.test.tiles.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
[
{
"name": "health-3857-z5",
"tileMatrix": "WebMercatorQuad",
"location": { "lat": -41.8899962, "lng": 174.0492437, "z": 5 },
"tileSet": "health"
},
{
"name": "health-2193-z5",
"tileMatrix": "NZTM2000Quad",
"location": { "lat": -41.8899962, "lng": 174.0492437, "z": 1 },
"tileSet": "aerial"
},
{
"name": "topographic-3857-z5",
"tileMatrix": "WebMercatorQuad",
"location": { "lat": -41.8899962, "lng": 174.0492437, "z": 5 },
"tileSet": "topographic",
"style": "topographic"
},
{
"name": "topolite-3857-z5",
"tileMatrix": "WebMercatorQuad",
"location": { "lat": -41.8899962, "lng": 174.0492437, "z": 5 },
"tileSet": "topographic",
"style": "topolite"
},
{
"name": "topographic-3857-z14",
"tileMatrix": "WebMercatorQuad",
"location": { "lat": -41.8899962, "lng": 174.0492437, "z": 14 },
"tileSet": "topographic",
"style": "topographic"
},
{
"name": "topolite-3857-z17",
"tileMatrix": "WebMercatorQuad",
"location": { "lat": -43.8063936, "lng": 172.9679876, "z": 17 },
"tileSet": "topographic",
"style": "topolite"
}
]
13 changes: 13 additions & 0 deletions packages/config-cli/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"target": "ES2020",
"lib": ["ES2020", "DOM"],
"module": "ES2020",
"moduleResolution": "node",
"rootDir": "./src",
"outDir": "./build"
},
"include": ["src/**/*"],
"references": [{ "path": "../__tests__" }]
}
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
{ "path": "./packages/bathymetry" },
{ "path": "./packages/_infra" },
{ "path": "./packages/config" },
{ "path": "./packages/config-cli" },
{ "path": "./packages/shared" },
{ "path": "./packages/lambda-cog" },
{ "path": "./packages/lambda-tiler" },
Expand Down
17 changes: 17 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6006,6 +6006,18 @@ pkg-dir@^4.2.0:
dependencies:
find-up "^4.0.0"

playwright-core@1.22.2:
version "1.22.2"
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.22.2.tgz#ed2963d79d71c2a18d5a6fd25b60b9f0a344661a"
integrity sha512-w/hc/Ld0RM4pmsNeE6aL/fPNWw8BWit2tg+TfqJ3+p59c6s3B6C8mXvXrIPmfQEobkcFDc+4KirNzOQ+uBSP1Q==

playwright@^1.22.0:
version "1.22.2"
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.22.2.tgz#353a7c29f89ca9600edc7a9a30aed790823c797d"
integrity sha512-hUTpg7LytIl3/O4t0AQJS1V6hWsaSY5uZ7w1oCC8r3a1AQN5d6otIdCkiB3cbzgQkcMaRxisinjMFMVqZkybdQ==
dependencies:
playwright-core "1.22.2"

pngjs@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-4.0.1.tgz#f803869bb2fc1bfe1bf99aa4ec21c108117cfdbe"
Expand Down Expand Up @@ -7995,6 +8007,11 @@ yocto-queue@^1.0.0:
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251"
integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==

zod@^3.17.3:
version "3.17.3"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.17.3.tgz#86abbc670ff0063a4588d85a4dcc917d6e4af2ba"
integrity sha512-4oKP5zvG6GGbMlqBkI5FESOAweldEhSOZ6LI6cG+JzUT7ofj1ZOC0PJudpQOpT1iqOFpYYtX5Pw0+o403y4bcg==

zod@^3.2.0:
version "3.5.1"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.5.1.tgz#e93ce58e182bb76f7d29ccd24feee72611f9a129"
Expand Down

0 comments on commit 39186d5

Please sign in to comment.