@grafana/plugin-e2e 3.5.0 → 3.5.1-canary.2579.24510886142.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,6 +3,9 @@
3
3
  function delay(ms) {
4
4
  return new Promise((resolve) => setTimeout(resolve, ms));
5
5
  }
6
+ function isTeardownError(error) {
7
+ return error instanceof Error && (error.message.includes("Target page, context or browser has been closed") || error.message.includes("Fetch response has been disposed"));
8
+ }
6
9
  async function handleBulkEvaluationRoute(route, flags, latency) {
7
10
  let response;
8
11
  try {
@@ -39,15 +42,21 @@ async function handleBulkEvaluationRoute(route, flags, latency) {
39
42
  headers: { "content-type": "application/json" }
40
43
  });
41
44
  } catch (error) {
45
+ if (isTeardownError(error)) {
46
+ return;
47
+ }
42
48
  console.error("@grafana/plugin-e2e: Failed to intercept OFREP bulk evaluation", error);
43
- if (response) {
44
- await route.fulfill({ response });
45
- } else {
46
- await route.fulfill({
47
- status: 500,
48
- body: JSON.stringify({ error: "Failed to intercept OFREP request" }),
49
- headers: { "content-type": "application/json" }
50
- });
49
+ try {
50
+ if (response) {
51
+ await route.fulfill({ response });
52
+ } else {
53
+ await route.fulfill({
54
+ status: 500,
55
+ body: JSON.stringify({ error: "Failed to intercept OFREP request" }),
56
+ headers: { "content-type": "application/json" }
57
+ });
58
+ }
59
+ } catch {
51
60
  }
52
61
  }
53
62
  }
@@ -74,12 +83,18 @@ async function handleSingleFlagRoute(route, flags, latency) {
74
83
  const response = await route.fetch();
75
84
  await route.fulfill({ response });
76
85
  } catch (error) {
86
+ if (isTeardownError(error)) {
87
+ return;
88
+ }
77
89
  console.error("@grafana/plugin-e2e: Failed to intercept OFREP single flag evaluation", error);
78
- await route.fulfill({
79
- status: 500,
80
- body: JSON.stringify({ error: "Failed to intercept OFREP request" }),
81
- headers: { "content-type": "application/json" }
82
- });
90
+ try {
91
+ await route.fulfill({
92
+ status: 500,
93
+ body: JSON.stringify({ error: "Failed to intercept OFREP request" }),
94
+ headers: { "content-type": "application/json" }
95
+ });
96
+ } catch {
97
+ }
83
98
  }
84
99
  }
85
100
  async function setupOpenFeatureRoutes(page, openFeature, latency, selectors) {
package/dist/index.d.ts CHANGED
@@ -264,8 +264,7 @@ declare class PanelEditOptionsGroup {
264
264
  getMultiSelect(label: string): MultiSelect;
265
265
  getColorPicker(label: string): ColorPicker;
266
266
  getUnitPicker(label: string): UnitPicker;
267
- private getByLabel;
268
- private getByTestId;
267
+ private getFieldLocator;
269
268
  private getOptionsGroupToggle;
270
269
  }
271
270
 
@@ -35,13 +35,16 @@ async function expectSelectToBe(select, value, options) {
35
35
  let actual = "";
36
36
  try {
37
37
  actual = await select.locator(select.ctx.selectors.constants.Select.singleValueContainer("")).innerText(options);
38
- test.expect(actual).toMatch(value);
39
- return {
40
- pass: true,
41
- actual,
42
- expected: value,
43
- message: () => `Value successfully selected`
44
- };
38
+ try {
39
+ test.expect(actual).toMatch(value);
40
+ return { pass: true, actual, expected: value, message: () => `Value successfully selected` };
41
+ } catch {
42
+ if (typeof value === "string" && value.endsWith("/" + actual.trim())) {
43
+ return { pass: true, actual, expected: value, message: () => `Value successfully selected` };
44
+ }
45
+ throw new Error(`Expected: ${value}
46
+ Received: ${actual}`);
47
+ }
45
48
  } catch (err) {
46
49
  return {
47
50
  message: () => utils.getMessage(value.toString(), err instanceof Error ? err.toString() : "Unknown error"),
@@ -34,67 +34,43 @@ class PanelEditOptionsGroup {
34
34
  await this.getOptionsGroupToggle().click();
35
35
  }
36
36
  getRadioGroup(label) {
37
- if (semver.gte(this.ctx.grafanaVersion, "13.0.0-24085625829")) {
38
- return new RadioGroup.RadioGroup(this.ctx, this.getByTestId(label).getByRole("radiogroup"));
39
- }
40
37
  if (semver.gte(this.ctx.grafanaVersion, "10.2.0")) {
41
- return new RadioGroup.RadioGroup(this.ctx, this.getByLabel(label).getByRole("radiogroup"));
38
+ return new RadioGroup.RadioGroup(this.ctx, this.getFieldLocator(label).getByRole("radiogroup"));
42
39
  }
43
- return new RadioGroup.RadioGroup(this.ctx, this.getByLabel(label));
40
+ return new RadioGroup.RadioGroup(this.ctx, this.getFieldLocator(label));
44
41
  }
45
42
  getSwitch(label) {
46
- if (semver.gte(this.ctx.grafanaVersion, "13.0.0-24085625829")) {
47
- return new Switch.Switch(this.ctx, this.getByTestId(label));
48
- }
49
- return new Switch.Switch(this.ctx, this.getByLabel(label));
43
+ return new Switch.Switch(this.ctx, this.getFieldLocator(label));
50
44
  }
51
45
  getTextInput(label) {
52
- if (semver.gte(this.ctx.grafanaVersion, "13.0.0-24085625829")) {
53
- return this.getByTestId(label).getByRole("textbox");
54
- }
55
- return this.getByLabel(label).getByRole("textbox");
46
+ return this.getFieldLocator(label).getByRole("textbox");
56
47
  }
57
48
  getNumberInput(label) {
58
- if (semver.gte(this.ctx.grafanaVersion, "13.0.0-24085625829")) {
59
- return this.getByTestId(label).getByRole("spinbutton");
60
- }
61
- return this.getByLabel(label).getByRole("spinbutton");
49
+ return this.getFieldLocator(label).getByRole("spinbutton");
62
50
  }
63
51
  getSliderInput(label) {
64
52
  if (semver.gte(this.ctx.grafanaVersion, "9.1.0")) {
65
53
  return this.getNumberInput(label);
66
54
  }
67
- return this.getByLabel(label).getByRole("textbox");
55
+ return this.getFieldLocator(label).getByRole("textbox");
68
56
  }
69
57
  getSelect(label) {
70
- if (semver.gte(this.ctx.grafanaVersion, "13.0.0-24085625829")) {
71
- return new Select.Select(this.ctx, this.getByTestId(label));
72
- }
73
- return new Select.Select(this.ctx, this.getByLabel(label));
58
+ return new Select.Select(this.ctx, this.getFieldLocator(label));
74
59
  }
75
60
  getMultiSelect(label) {
76
- if (semver.gte(this.ctx.grafanaVersion, "13.0.0-24085625829")) {
77
- return new MultiSelect.MultiSelect(this.ctx, this.getByTestId(label));
78
- }
79
- return new MultiSelect.MultiSelect(this.ctx, this.getByLabel(label));
61
+ return new MultiSelect.MultiSelect(this.ctx, this.getFieldLocator(label));
80
62
  }
81
63
  getColorPicker(label) {
82
- if (semver.gte(this.ctx.grafanaVersion, "13.0.0-24085625829")) {
83
- return new ColorPicker.ColorPicker(this.ctx, this.getByTestId(label));
84
- }
85
- return new ColorPicker.ColorPicker(this.ctx, this.getByLabel(label));
64
+ return new ColorPicker.ColorPicker(this.ctx, this.getFieldLocator(label));
86
65
  }
87
66
  getUnitPicker(label) {
88
- if (semver.gte(this.ctx.grafanaVersion, "13.0.0-24085625829")) {
89
- return new UnitPicker.UnitPicker(this.ctx, this.getByTestId(label));
90
- }
91
- return new UnitPicker.UnitPicker(this.ctx, this.getByLabel(label));
92
- }
93
- getByLabel(optionLabel) {
94
- return this.element.getByLabel(`${this.groupLabel} ${optionLabel} field property editor`);
67
+ return new UnitPicker.UnitPicker(this.ctx, this.getFieldLocator(label));
95
68
  }
96
- getByTestId(optionLabel) {
97
- return this.element.getByTestId(`data-testid ${this.groupLabel} ${optionLabel} field property editor`);
69
+ getFieldLocator(optionLabel) {
70
+ const selector = utils.resolveGrafanaSelector(
71
+ this.ctx.selectors.components.PanelEditor.OptionsPane.fieldLabel(`${this.groupLabel} ${optionLabel}`)
72
+ );
73
+ return this.element.locator(selector);
98
74
  }
99
75
  getOptionsGroupToggle() {
100
76
  const selector = utils.resolveGrafanaSelector(this.ctx.selectors.components.OptionsGroup.toggle(this.groupLabel));
@@ -1,7 +1,6 @@
1
1
  'use strict';
2
2
 
3
3
  var ComponentBase = require('./ComponentBase.js');
4
- var semver = require('semver');
5
4
  var utils = require('../utils.js');
6
5
 
7
6
  class Select extends ComponentBase.ComponentBase {
@@ -10,6 +9,7 @@ class Select extends ComponentBase.ComponentBase {
10
9
  }
11
10
  async selectOption(values, options) {
12
11
  const menu = await openSelect(this, options);
12
+ await this.locator().page().keyboard.type(values);
13
13
  return selectByValueOrLabel(values, menu, this.ctx, options);
14
14
  }
15
15
  }
@@ -19,8 +19,12 @@ async function openSelect(component, options) {
19
19
  await element.getByRole("combobox").click(options);
20
20
  return element.page().locator(utils.resolveGrafanaSelector(selectors.components.Select.menu));
21
21
  }
22
- async function selectByValueOrLabel(labelOrValue, menu, ctx, options) {
23
- const option = getOption(menu, ctx).getByText(labelOrValue, { exact: true });
22
+ async function selectByValueOrLabel(labelOrValue, menu, _ctx, options) {
23
+ const allOptions = getOption(menu);
24
+ let option = allOptions.getByText(labelOrValue, { exact: true });
25
+ if (!await option.count() && await allOptions.count() === 1) {
26
+ option = allOptions.first();
27
+ }
24
28
  const value = await option.textContent(options);
25
29
  await option.click(options);
26
30
  if (!value) {
@@ -28,11 +32,8 @@ async function selectByValueOrLabel(labelOrValue, menu, ctx, options) {
28
32
  }
29
33
  return value;
30
34
  }
31
- function getOption(menu, ctx) {
32
- if (semver.gte(ctx.grafanaVersion, "11.0.0")) {
33
- return menu.getByRole("option");
34
- }
35
- return menu.getByLabel("Select option");
35
+ function getOption(menu) {
36
+ return menu.getByRole("option").or(menu.getByLabel("Select option"));
36
37
  }
37
38
 
38
39
  exports.Select = Select;
@@ -120,7 +120,8 @@ class DashboardPage extends GrafanaPage.GrafanaPage {
120
120
  await this.getByGrafanaSelector(pages.Dashboard.Sidebar.addButton).click();
121
121
  }
122
122
  await this.getByGrafanaSelector(components.Sidebar.newPanelButton).click();
123
- await this.getByGrafanaSelector(components.Sidebar.configurePanelButton).click();
123
+ const configureButton = semver__namespace.lt(this.ctx.grafanaVersion, "13.1.0") ? this.getByGrafanaSelector(components.Sidebar.container).getByRole("button", { name: "Configure" }) : this.getByGrafanaSelector(components.Sidebar.configurePanelButton);
124
+ await configureButton.click();
124
125
  } else if (semver__namespace.gte(this.ctx.grafanaVersion, "9.5.0")) {
125
126
  let addButton = this.getByGrafanaSelector(
126
127
  components.PageToolbar.itemButton(constants.PageToolBar.itemButtonTitle)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grafana/plugin-e2e",
3
- "version": "3.5.0",
3
+ "version": "3.5.1-canary.2579.24510886142.0",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "files": [
@@ -49,10 +49,10 @@
49
49
  "dotenv": "^17.2.4"
50
50
  },
51
51
  "dependencies": {
52
- "@grafana/e2e-selectors": "13.1.0-24335230309",
52
+ "@grafana/e2e-selectors": "13.1.0-24448182242",
53
53
  "semver": "^7.5.4",
54
54
  "uuid": "^13.0.0",
55
55
  "yaml": "^2.3.4"
56
56
  },
57
- "gitHead": "0b567b0d9f94a1fbb68a3d978481b450cc4206d9"
57
+ "gitHead": "8d17e017e0337204a0303ecfbb8890a0ba7daadd"
58
58
  }