Skip to content

Commit 2a90208

Browse files
committed
Change contentPreference from single- to multi-select. Remove 'no-preference'.
Get tests working Enable CI tests Add preferred-content tests for multiple content preferences
1 parent 94b3f91 commit 2a90208

File tree

10 files changed

+126
-60
lines changed

10 files changed

+126
-60
lines changed

.github/workflows/ci-testing.yml

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,15 @@ jobs:
1111
- uses: actions/checkout@v4
1212
- name: Use Node.js
1313
uses: actions/setup-node@v4
14-
with:
15-
node-version: latest
16-
# - run: sudo apt-get install xvfb
17-
# - run: npm install
18-
# - run: npx playwright install
19-
# - run: xvfb-run --auto-servernum -- npm test
20-
env:
21-
CI: true
14+
with:
15+
node-version: latest
16+
- name: Install XVFB
17+
run: sudo apt-get install -y xvfb
18+
- name: Install Dependencies
19+
run: npm install
20+
- name: Install Playwright
21+
run: npx playwright install
22+
- name: Run Tests with XVFB
23+
run: xvfb-run --auto-servernum -- npm test
24+
env:
25+
CI: true

src/background.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,7 @@ chrome.runtime.onInstalled.addListener(async () => {
8686
featureIndexOverlayOption: false,
8787
renderMap: true,
8888
defaultExtCoor: 'pcrs',
89-
defaultLocCoor: 'gcrs',
90-
defaultContentPreference: 'no-preference'
89+
defaultLocCoor: 'gcrs'
9190
}
9291
});
9392
registerContentScripts();

src/popup.html

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,10 @@ <h6 class="card-title">Accessibility Settings</h6>
6363
<h6 class="card-title">Content Preferences</h6>
6464
<div>
6565
<label class="form-label" for="content-prefs">Preferred map content type: </label>
66-
<select class="form-select form-select-sm" id="contentPreference">
67-
<option value="no-preference" selected>No preference (default)</option>
66+
<select class="form-select form-select-sm" multiple id="contentPreference">
6867
<option value="image">Images</option>
69-
<option value="tiled-image">Tiled images</option>
68+
<option value="tile">Tiles</option>
7069
<option value="feature">Features</option>
71-
<option value="vector-tile">Vector tiles</option>
7270
<option value="table">Tables</option>
7371
</select>
7472
</div>

src/popup.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ function loadOptions() {
2222
featureIndexOverlayOption: false,
2323
renderMap: false,
2424
defaultExtCoor: 'pcrs',
25-
defaultLocCoor: 'gcrs',
26-
defaultContentPreference: 'no-preference'
25+
defaultLocCoor: 'gcrs'
2726
};
2827
for (let name in options) {
2928
let elem = document.getElementById(name);
@@ -36,6 +35,15 @@ function loadOptions() {
3635
Array.from(elem.children).forEach(el => el.value === options[name]?
3736
el.selected = true : el.selected = false);
3837
break;
38+
case "object":
39+
if (Array.isArray(options[name])) {
40+
Array.from(elem.children).forEach(o => {
41+
if (options[name].includes(o.value)) {
42+
o.defaultSelected = true;
43+
}
44+
});
45+
}
46+
break;
3947
}
4048
}
4149
}
@@ -55,7 +63,11 @@ function handleCheckboxChange(e) {
5563

5664
function handleDropdownChange(e) {
5765
let option = e.target.id;
58-
options[option] = Array.from(e.target.children).find(el => el.selected).value;
66+
if (option === 'contentPreference') {
67+
options[option] = Array.from(e.target.children).filter(el => el.selected).map( el => el.value);
68+
} else {
69+
options[option] = Array.from(e.target.children).find(el => el.selected).value;
70+
}
5971
saveOptions();
6072
}
6173

test/e2e/basics/locale.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
<!DOCTYPE html>
2-
<html lang="en">
2+
<html>
3+
<!-- the lang attribute, exceptionally in en and fr now force the map locale -->
4+
<!-- consequently, to test correct localization / internationalization
5+
remove the lang attribute, or change it to something not en or fr,
6+
map will use the locale strings injected by the extension -->
37

48
<head>
59
<title>Static Features Test</title>

test/e2e/basics/locale.test.js

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,44 +38,44 @@ test.describe("Locale Tests", () => {
3838
expect(zoomInTitle).toBe("Zoom in");
3939
expect(zoomOutTitle).toBe("Zoom out");
4040
expect(reloadTitle).toBe("Reload");
41-
expect(fullScreenTitle).toBe("View Fullscreen");
41+
expect(fullScreenTitle).toBe("View fullscreen");
4242
});
4343
});
4444

4545
test.describe("Other Locale Tests", () => {
46-
let frContext, frPage;
46+
let svContext, svPage;
4747
test.beforeAll(async () => {
4848
let pathToExtension = path.join(__dirname, '../../../src/');
49-
50-
frContext = await chromium.launchPersistentContext("",{
49+
// update to swedish because en and fr locales are 'forced' by the lang attribute
50+
svContext = await chromium.launchPersistentContext("",{locale: 'sv',
5151
headless: false,
5252
slowMo: 50,
5353
args: [
54-
'--lang=fr',
54+
'--lang=sv',
5555
`--disable-extensions-except=${pathToExtension}`,
5656
`--load-extension=${pathToExtension}`
57-
],
57+
]
5858
});
59-
let [background] = frContext.serviceWorkers();
59+
let [background] = svContext.serviceWorkers();
6060
if (!background)
61-
background = await frContext.waitForEvent("serviceworker");
61+
background = await svContext.waitForEvent("serviceworker");
6262
const id = background.url().split("/")[2];
63-
let newPage = await frContext.newPage();
63+
let newPage = await svContext.newPage();
6464
await newPage.goto('chrome-extension://' + id +'/popup.html', {waitUntil: "load"});
65-
frPage = await frContext.newPage();
66-
await frPage.goto("test/e2e/basics/locale.html", {waitUntil: "load"});
65+
svPage = await svContext.newPage();
66+
await svPage.goto("test/e2e/basics/locale.html", {waitUntil: "load"});
6767
});
6868

6969
test.afterAll(async () => {
70-
await frContext.close();
70+
await svContext.close();
7171
});
7272

7373
test("UI button titles", async () => {
74-
let reloadTitle = await frPage.$eval(
74+
let reloadTitle = await svPage.$eval(
7575
"xpath=//html/body/mapml-viewer >> css=div > div.leaflet-control-container > div.leaflet-top.leaflet-left > div.mapml-reload-button.leaflet-bar.leaflet-control > button",
7676
(tile) => tile.title
7777
);
7878

79-
expect(reloadTitle).toBe("Rechargez");
79+
expect(reloadTitle).toBe("Läs In Igen");
8080
});
8181
});

test/e2e/basics/popup.test.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,18 @@ test.describe("Popup test", () => {
9292

9393
let newPage = await context.newPage();
9494
await newPage.goto("test/e2e/basics/popup.test.html", { waitUntil: "load" });
95-
newPage.waitForTimeout(500);
95+
await newPage.waitForTimeout(1000);
9696
await newPage.click("body > mapml-viewer");
9797
await newPage.keyboard.press("Shift+F10");
9898
await newPage.keyboard.press("Tab");
99+
await newPage.waitForTimeout(100);
99100
await newPage.keyboard.press("Enter");
100101
await newPage.keyboard.press("Tab");
102+
await newPage.waitForTimeout(100);
101103
await newPage.keyboard.press("Tab");
104+
await newPage.waitForTimeout(100);
102105
await newPage.keyboard.press("Enter");
106+
await newPage.waitForTimeout(100);
103107

104108
const text = await newPage.evaluate(() => navigator.clipboard.readText());
105109
const coordinates = await newPage.evaluate((t) => {
@@ -119,7 +123,7 @@ test.describe("Popup test", () => {
119123

120124
let newPage = await context.newPage();
121125
await newPage.goto("test/e2e/basics/popup.test.html", { waitUntil: "load" });
122-
newPage.waitForTimeout(500);
126+
await newPage.waitForTimeout(500);
123127
await newPage.click("body > mapml-viewer");
124128
await newPage.keyboard.press("Shift+F10");
125129
await newPage.keyboard.press("Tab");

test/e2e/basics/preferred-content.html

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,26 @@
55
<meta name="viewport" content="width=device-width,initial-scale=1">
66
<title>Preferred Content Test</title>
77
<script type="module" src="../../../src/dist/mapml.js"></script>
8+
<script>
9+
document.addEventListener('DOMContentLoaded',(e)=>{
10+
let l, map = document.querySelector('mapml-viewer'),
11+
prefersEverything = map.matchMedia('(prefers-map-content: image) and (prefers-map-content: tile) and (prefers-map-content: feature) and (prefers-map-content: table)').matches === 'true',
12+
t = document.querySelector('template'),
13+
prefersFeaturesOnly = map.matchMedia('(prefers-map-content: feature) and ( not ((prefers-map-content: image) or (prefers-map-content: tile)))').matches === 'true',
14+
prefersTiles = map.matchMedia('(prefers-map-content: tile');
15+
if (prefersFeaturesOnly) {
16+
l = t.content.querySelector('#features').cloneNode(true);
17+
} else if (prefersImages) {
18+
l = t.content.querySelector('#wms').cloneNode(true);
19+
} else if (prefersTiles) {
20+
l = t.content.querySelector('#tiles').cloneNode(true);
21+
}
22+
map.appendChild(l);
23+
});
24+
</script>
825
</head>
926
<body>
10-
<mapml-viewer style="height: 500px;width:500px;" projection="CBMTILE" zoom="8" lat="46.51231982020816" lon="-63.25669692277839" controls>
27+
<mapml-viewer data-testid="viewer" style="height: 500px;width:500px;" projection="CBMTILE" zoom="8" lat="46.51231982020816" lon="-63.25669692277839" controls>
1128
<map-layer data-testid="test-layer" label="Provinces and Territories" src="../data/cbmt-cbmtile.mapml" checked></map-layer>
1229
</mapml-viewer>
1330
</body>

test/e2e/basics/preferred-content.test.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ test.describe("Preferred content test", () => {
3434
test("User prefers feature content type", async () => {
3535
// "page" is the extension popup, hasn't been closed so still open in a
3636
// browser tab somewhere...
37+
await page.bringToFront();
3738
await page.keyboard.press("Tab");
3839
await page.keyboard.press("Tab");
3940
await page.keyboard.press("Tab");
@@ -55,5 +56,56 @@ test.describe("Preferred content test", () => {
5556
const label = await layer.evaluate((l) => l._layerControlLabel.textContent);
5657
expect(label).toEqual('Feature content');
5758
});
59+
60+
test("Multiple preferences can be expressed by user", async () => {
61+
await page.bringToFront();
62+
await page.keyboard.press("Tab");
63+
await page.keyboard.press("Tab");
64+
await page.keyboard.press("Tab");
65+
await page.keyboard.press("Tab");
66+
await page.keyboard.press("Tab");
67+
await page.keyboard.press("Tab");
68+
await page.keyboard.press("Tab");
69+
await page.keyboard.press("Tab");
70+
// features is currently selected, so need a tricky set of key presses
71+
await page.keyboard.press("ArrowUp");
72+
await page.keyboard.press("ArrowUp");
73+
await page.keyboard.press("Shift+ArrowDown");
74+
await page.keyboard.press("Shift+ArrowDown");
75+
await page.keyboard.press("Shift+ArrowDown");
76+
let newPage = await context.newPage();
77+
await newPage.goto("test/e2e/basics/preferred-content.html", { waitUntil: "domcontentloaded" });
78+
await newPage.waitForTimeout(1000);
79+
let map = newPage.getByTestId('viewer');
80+
const matches = await map.evaluate((map)=>{
81+
return map.matchMedia('(prefers-map-content: image) and (prefers-map-content: tile) and (prefers-map-content: feature) and (prefers-map-content: table)').matches;
82+
});
83+
expect(matches).toBe(true);
84+
});
85+
test("Multiple disjoint preferences can be expressed by user", async () => {
86+
await page.bringToFront();
87+
await page.keyboard.press("Tab");
88+
await page.keyboard.press("Tab");
89+
await page.keyboard.press("Tab");
90+
await page.keyboard.press("Tab");
91+
await page.keyboard.press("Tab");
92+
await page.keyboard.press("Tab");
93+
await page.keyboard.press("Tab");
94+
await page.keyboard.press("Tab");
95+
await page.keyboard.press("ArrowUp");
96+
await page.keyboard.press("ArrowUp");
97+
await page.keyboard.press(" "); // select tiles option
98+
await page.keyboard.press("Control+ArrowDown");
99+
await page.keyboard.press("Control+ArrowDown");
100+
await page.keyboard.press(" "); // select tables option
101+
let newPage = await context.newPage();
102+
await newPage.goto("test/e2e/basics/preferred-content.html", { waitUntil: "domcontentloaded" });
103+
await newPage.waitForTimeout(1000);
104+
let map = newPage.getByTestId('viewer');
105+
const matches = await map.evaluate((map)=>{
106+
return map.matchMedia('(not (prefers-map-content: image)) and (prefers-map-content: tile) and (not (prefers-map-content: feature)) and (prefers-map-content: table)').matches;
107+
});
108+
expect(matches).toBe(true);
109+
});
58110

59111
});

test/e2e/basics/render.test.js

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ test.describe("Render MapML resources test", () => {
4949
await page.keyboard.press("Equal");
5050
await page.waitForTimeout(1000);
5151
}
52-
await page.waitForTimeout(500);
52+
await page.waitForTimeout(1000);
5353
expect(page.url()).toContain("#5,-89.7827040843159,60.27815582468662");
5454
await page.goBack({waitUntil: "networkidle"});
5555
expect(page.url()).toContain("about:blank");
@@ -79,14 +79,6 @@ test.describe("Render MapML resources test", () => {
7979
});
8080

8181
test("Render map from text/mapml document", async () => {
82-
//Changes page.goto response (initial page load) to be of content type text/mapml
83-
await page.route("test/e2e/basics/test.mapml", async route => {
84-
const response = await page.request.fetch("test/e2e/basics/test.mapml");
85-
await route.fulfill({
86-
body: await response.body(),
87-
contentType: 'text/mapml'
88-
});
89-
});
9082
await page.goto("test/e2e/basics/test.mapml");
9183
const map = await page.waitForFunction(() => document.querySelector("mapml-viewer"));
9284

@@ -134,29 +126,13 @@ test.describe("Render MapML resources test", () => {
134126
});
135127

136128
test("Projection defaults to OSMTILE in the case of unknown projection", async () => {
137-
//Changes page.goto response (initial page load) to be of content type text/mapml
138-
await page.route("test/e2e/basics/unknown_projection.mapml", async route => {
139-
const response = await page.request.fetch("test/e2e/basics/unknown_projection.mapml");
140-
await route.fulfill({
141-
body: await response.body(),
142-
contentType: 'text/mapml'
143-
});
144-
});
145129
await page.goto("test/e2e/basics/unknown_projection.mapml");
146130
const map = await page.waitForFunction(() => document.querySelector("mapml-viewer"));
147131
const projection = await map.getAttribute('projection');
148132
expect(projection).toEqual("OSMTILE");
149133
}, {times: 1});
150134

151135
test.skip("Projection from map-meta[content*=projection] attribute / mime type parameter", async () => {
152-
//Changes page.goto response (initial page load) to be of content type text/mapml
153-
await page.route("test/e2e/basics/content-type-projection.mapml", async route => {
154-
const response = await page.request.fetch("test/e2e/basics/content-type-projection.mapml");
155-
await route.fulfill({
156-
body: await response.body(),
157-
contentType: 'text/mapml'
158-
});
159-
});
160136
await page.waitForTimeout(1000);
161137
await page.goto("test/e2e/basics/content-type-projection.mapml");
162138
await page.waitForTimeout(1000);

0 commit comments

Comments
 (0)