improve abstraction

This commit is contained in:
HarelM
2026-07-09 14:27:33 +03:00
parent 8580499ec3
commit a251faf8f7
5 changed files with 39 additions and 52 deletions
+3 -8
View File
@@ -176,9 +176,7 @@ describe("layer editor", () => {
await when.collapseGroupInLayerEditor(); await when.collapseGroupInLayerEditor();
await when.collapseGroupInLayerEditor(1); await when.collapseGroupInLayerEditor(1);
await when.collapseGroupInLayerEditor(2); await when.collapseGroupInLayerEditor(2);
await when.doWithin("spec-field:text-font", async () => { await when.clickWithin("spec-field:text-font", ".maputnik-autocomplete input");
await get.element(".maputnik-autocomplete input").first().click();
});
await then(get.element(".maputnik-autocomplete-menu-item")).shouldBeVisible(); await then(get.element(".maputnik-autocomplete-menu-item")).shouldBeVisible();
await then(get.element(".maputnik-autocomplete-menu-item")).shouldHaveLength(3); await then(get.element(".maputnik-autocomplete-menu-item")).shouldHaveLength(3);
}); });
@@ -202,8 +200,7 @@ describe("layer editor", () => {
layers: [{ id, type: "circle", source: "example" }], layers: [{ id, type: "circle", source: "example" }],
}); });
const sourceText = get.elementByText('"source"'); await when.clickByText('"source"');
await sourceText.click();
await when.typeKeys('"'); await when.typeKeys('"');
await then(get.element(".cm-lint-marker-error")).shouldExist(); await then(get.element(".cm-lint-marker-error")).shouldExist();
@@ -239,9 +236,7 @@ describe("layer editor", () => {
const header = get.elementByTestId("layer-editor.header"); const header = get.elementByTestId("layer-editor.header");
await then(header).shouldBeVisible(); await then(header).shouldBeVisible();
await get await when.scrollToBottom(get.element(".maputnik-scroll-container"));
.element(".maputnik-scroll-container")
.evaluate((el) => el.scrollTo(0, el.scrollHeight));
await when.wait(200); await when.wait(200);
await then(header).shouldBeVisible(); await then(header).shouldBeVisible();
+1 -1
View File
@@ -342,7 +342,7 @@ describe("layers list", () => {
await then(header).shouldBeVisible(); await then(header).shouldBeVisible();
// Scroll the layer list container // Scroll the layer list container
await get.elementByTestId("layer-list").evaluate((el) => el.scrollTo(0, el.scrollHeight)); await when.scrollToBottom(get.elementByTestId("layer-list"));
await when.wait(200); await when.wait(200);
await then(header).shouldBeVisible(); await then(header).shouldBeVisible();
await then(get.elementByTestId("layer-list:add-layer")).shouldBeVisible(); await then(get.elementByTestId("layer-list:add-layer")).shouldBeVisible();
+28 -34
View File
@@ -203,7 +203,6 @@ async function centerOf(locator: Locator): Promise<{ x: number; y: number }> {
} }
export class MaputnikDriver { export class MaputnikDriver {
private scope: Locator | null = null;
private readonly recordedRequests = new Map<string, Request[]>(); private readonly recordedRequests = new Map<string, Request[]>();
private readonly modalDriver = new ModalDriver(this); private readonly modalDriver = new ModalDriver(this);
@@ -217,12 +216,8 @@ export class MaputnikDriver {
// ---- Element access ------------------------------------------------------ // ---- Element access ------------------------------------------------------
private root(): Page | Locator {
return this.scope ?? this.page;
}
private testId(testId: string): Locator { private testId(testId: string): Locator {
return this.root().locator(testIdSelector(testId)); return this.page.locator(testIdSelector(testId));
} }
then = <T>(target: T) => new MaputnikAssertable(target, this.page); then = <T>(target: T) => new MaputnikAssertable(target, this.page);
@@ -307,16 +302,6 @@ export class MaputnikDriver {
typeKeys: (keys: string) => typeSequence(this.page, keys), typeKeys: (keys: string) => typeSequence(this.page, keys),
doWithin: async (selector: string, fn: () => Promise<void> | void) => {
const previous = this.scope;
this.scope = (previous ?? this.page).locator(testIdSelector(selector));
try {
await fn();
} finally {
this.scope = previous;
}
},
click: async (testId: string, index = 0) => { click: async (testId: string, index = 0) => {
// Documentation buttons are wrapped in a <label>/.maputnik-doc-target that // Documentation buttons are wrapped in a <label>/.maputnik-doc-target that
// Playwright treats as intercepting the click; bypass the check for them. // Playwright treats as intercepting the click; bypass the check for them.
@@ -345,7 +330,23 @@ export class MaputnikDriver {
}, },
selectWithin: async (selector: string, value: string) => { selectWithin: async (selector: string, value: string) => {
await this.root().locator(testIdSelector(selector)).locator("select").selectOption(value); await this.testId(selector).locator("select").selectOption(value);
},
clickWithin: async (parentTestId: string, selector: string) => {
await this.testId(parentTestId).locator(selector).first().click();
},
clickByText: async (text: string) => {
await this.page.getByText(text).click();
},
clickByAttribute: async (attribute: string, value: string) => {
await this.page.locator(`[${attribute}="${value}"]`).click();
},
scrollToBottom: async (element: Locator) => {
await element.evaluate((el) => el.scrollTo(0, el.scrollHeight));
}, },
setValue: async (testId: string, text: string) => { setValue: async (testId: string, text: string) => {
@@ -364,20 +365,18 @@ export class MaputnikDriver {
}, },
setValueToPropertyArray: async (selector: string, value: string) => { setValueToPropertyArray: async (selector: string, value: string) => {
await this.when.doWithin(selector, async () => { const block = this.testId(selector);
const input = this.root().locator(".maputnik-array-block-content input").last(); const input = block.locator(".maputnik-array-block-content input").last();
await input.focus(); await input.focus();
await typeSequence(this.page, "{selectall}" + value); await typeSequence(this.page, "{selectall}" + value);
});
}, },
addValueToPropertyArray: async (selector: string, value: string) => { addValueToPropertyArray: async (selector: string, value: string) => {
await this.when.doWithin(selector, async () => { const block = this.testId(selector);
await this.root().locator(".maputnik-array-add-value").click(); await block.locator(".maputnik-array-add-value").click();
const input = this.root().locator(".maputnik-array-block-content input").last(); const input = block.locator(".maputnik-array-block-content input").last();
await input.focus(); await input.focus();
await typeSequence(this.page, "{selectall}" + value); await typeSequence(this.page, "{selectall}" + value);
});
}, },
setStyle: async ( setStyle: async (
@@ -525,15 +524,10 @@ export class MaputnikDriver {
public get = { public get = {
isMac: () => isMac, isMac: () => isMac,
element: (selector: string) => this.root().locator(selector), element: (selector: string) => this.page.locator(selector),
elementByTestId: (testId: string) => this.testId(testId), elementByTestId: (testId: string) => this.testId(testId),
elementByText: (text: string) => this.root().getByText(text),
elementByAttribute: (attribute: string, value: string) =>
this.root().locator(`[${attribute}="${value}"]`),
canvas: () => this.page.locator("canvas"), canvas: () => this.page.locator("canvas"),
searchControl: () => this.page.locator(".maplibregl-ctrl-geocoder"), searchControl: () => this.page.locator(".maplibregl-ctrl-geocoder"),
+6 -8
View File
@@ -14,14 +14,12 @@ export class ModalDriver {
await when.type("add-layer.layer-id.input", id); await when.type("add-layer.layer-id.input", id);
if (opts.layer) { if (opts.layer) {
await when.doWithin("add-layer.layer-source-block", async () => { const input = get.elementByTestId("add-layer.layer-source-block").locator("input");
const input = get.element("input"); await input.click();
await input.click(); await input.fill(opts.layer);
await input.fill(opts.layer!); // The source input is a controlled downshift combobox; wait for React to
// The source input is a controlled downshift combobox; wait for React // settle on the typed value before submitting.
// to settle on the typed value before submitting. await expect(input).toHaveValue(opts.layer);
await expect(input).toHaveValue(opts.layer!);
});
// Close the autocomplete menu so it does not intercept the add button. // Close the autocomplete menu so it does not intercept the add button.
await get.elementByTestId("add-layer.layer-id.input").click(); await get.elementByTestId("add-layer.layer-id.input").click();
} }
+1 -1
View File
@@ -271,7 +271,7 @@ describe("modals", () => {
await when.click("modal:settings.close-modal"); await when.click("modal:settings.close-modal");
await when.click("nav:open"); await when.click("nav:open");
await get.elementByAttribute("aria-label", "MapTiler Basic").click(); await when.clickByAttribute("aria-label", "MapTiler Basic");
await when.wait(1000); await when.wait(1000);
await when.click("nav:settings"); await when.click("nav:settings");