@grafana/plugin-e2e 3.7.1 → 3.7.2-canary.2560.fc1fa7a.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.
- package/dist/fixtures/components.js +9 -0
- package/dist/index.d.ts +60 -5
- package/dist/index.js +6 -0
- package/dist/models/Components.js +18 -0
- package/dist/models/components/DataSourcePicker.js +2 -6
- package/dist/models/components/PanelEditOptionsGroup.js +2 -2
- package/dist/models/components/ScopedComponent.js +20 -0
- package/dist/models/components/TimeRange.js +3 -6
- package/dist/models/pages/DashboardPage.js +14 -0
- package/package.json +3 -3
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var Components = require('../models/Components.js');
|
|
4
|
+
|
|
5
|
+
const components = async ({ request, page, selectors, grafanaVersion }, use, testInfo) => {
|
|
6
|
+
await use(new Components.Components({ page, selectors, grafanaVersion, request, testInfo }));
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
exports.components = components;
|
package/dist/index.d.ts
CHANGED
|
@@ -49,9 +49,21 @@ declare abstract class GrafanaPage {
|
|
|
49
49
|
waitForQueryDataResponse(cb?: (request: Response$1) => boolean | Promise<boolean>): Promise<Response$1>;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Base class for components that live at the page level but can optionally
|
|
54
|
+
* be scoped to a sub-tree of the DOM via `within()`.
|
|
55
|
+
*/
|
|
56
|
+
declare abstract class ScopedComponent extends GrafanaPage {
|
|
57
|
+
protected readonly root?: Locator | undefined;
|
|
54
58
|
constructor(ctx: PluginTestCtx, root?: Locator | undefined);
|
|
59
|
+
/**
|
|
60
|
+
* Returns a new instance of this component scoped to the given root locator.
|
|
61
|
+
* Mirrors Playwright's `locator.locator(...)` chaining pattern.
|
|
62
|
+
*/
|
|
63
|
+
within(root: Locator): this;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
declare class DataSourcePicker extends ScopedComponent {
|
|
55
67
|
/**
|
|
56
68
|
* Sets the data source picker to the provided name
|
|
57
69
|
*/
|
|
@@ -159,14 +171,34 @@ declare class AppPage extends GrafanaPage {
|
|
|
159
171
|
goto(options?: AppPageNavigateOptions): Promise<void>;
|
|
160
172
|
}
|
|
161
173
|
|
|
162
|
-
declare class TimeRange extends
|
|
163
|
-
constructor(ctx: PluginTestCtx);
|
|
174
|
+
declare class TimeRange extends ScopedComponent {
|
|
164
175
|
/**
|
|
165
176
|
* Opens the time picker and sets the time range to the provided values
|
|
166
177
|
*/
|
|
167
178
|
set({ from, to, zone }: TimeRangeArgs): Promise<void>;
|
|
168
179
|
}
|
|
169
180
|
|
|
181
|
+
/**
|
|
182
|
+
* Factory for components that are not attached to a specific page.
|
|
183
|
+
*
|
|
184
|
+
* Use this when you need to interact with a Grafana UI component on a page
|
|
185
|
+
* that is not covered by one of the page fixtures (e.g. {@link PanelEditPage}
|
|
186
|
+
* or {@link ExplorePage}).
|
|
187
|
+
*
|
|
188
|
+
* To scope a component to a sub-tree of the DOM, use `within(root)`:
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```typescript
|
|
192
|
+
* await components.dataSourcePicker.set('prom');
|
|
193
|
+
* await components.dataSourcePicker.within(panel).set('prom');
|
|
194
|
+
* ```
|
|
195
|
+
*/
|
|
196
|
+
declare class Components {
|
|
197
|
+
readonly dataSourcePicker: DataSourcePicker;
|
|
198
|
+
readonly timeRangePicker: TimeRange;
|
|
199
|
+
constructor(ctx: PluginTestCtx);
|
|
200
|
+
}
|
|
201
|
+
|
|
170
202
|
declare class Panel extends GrafanaPage {
|
|
171
203
|
readonly ctx: PluginTestCtx;
|
|
172
204
|
readonly locator: Locator;
|
|
@@ -359,6 +391,14 @@ declare class DashboardPage extends GrafanaPage {
|
|
|
359
391
|
* Navigates to the dashboard page. If a dashboard uid was not provided, it's assumed that it's a new dashboard.
|
|
360
392
|
*/
|
|
361
393
|
goto(options?: NavigateOptions): Promise<void>;
|
|
394
|
+
/**
|
|
395
|
+
* Returns a locator for the dashboard toolbar area that contains the time range controls.
|
|
396
|
+
*
|
|
397
|
+
* - Grafana ≥ 11.1.0: resolves to `Dashboard.Controls` (scenes-based dashboard controls bar)
|
|
398
|
+
* - Grafana 9.4.0–11.0.x: resolves to `NavToolbar.container`
|
|
399
|
+
* - Grafana < 9.4.0: falls back to `.page-toolbar`
|
|
400
|
+
*/
|
|
401
|
+
get toolbar(): _playwright_test.Locator;
|
|
362
402
|
/**
|
|
363
403
|
* Scrolls the page viewport-by-viewport to trigger below-fold panel queries.
|
|
364
404
|
*
|
|
@@ -974,6 +1014,21 @@ type PluginFixture = {
|
|
|
974
1014
|
* You can use this in conjunction with the .toHaveNoA11yViolations matcher to assert that there are no accessibility violations on the page.
|
|
975
1015
|
*/
|
|
976
1016
|
scanForA11yViolations: (context?: AxeScanContext) => Promise<AxeResults>;
|
|
1017
|
+
/**
|
|
1018
|
+
* Factory for components that are not attached to a specific page.
|
|
1019
|
+
*
|
|
1020
|
+
* Use this fixture to interact with a Grafana UI component on a page that is
|
|
1021
|
+
* not covered by other page fixtures (e.g. {@link PanelEditPage} or {@link ExplorePage}).
|
|
1022
|
+
*
|
|
1023
|
+
* @example
|
|
1024
|
+
* ```typescript
|
|
1025
|
+
* test('my test', async ({ components }) => {
|
|
1026
|
+
* await components.dataSourcePicker.set('gdev-prometheus');
|
|
1027
|
+
* await components.dataSourcePicker.within(someLocator).set('gdev-tempo');
|
|
1028
|
+
* });
|
|
1029
|
+
* ```
|
|
1030
|
+
*/
|
|
1031
|
+
components: Components;
|
|
977
1032
|
};
|
|
978
1033
|
/**
|
|
979
1034
|
* @alpha - the API for accessibility scanning is still being finalized and may change in future releases. Feedback is welcome!
|
|
@@ -1506,5 +1561,5 @@ declare global {
|
|
|
1506
1561
|
}
|
|
1507
1562
|
}
|
|
1508
1563
|
|
|
1509
|
-
export { AnnotationEditPage, AnnotationPage, AppConfigPage, AppPage, DEFAULT_A11Y_TAGS, DashboardPage, DataSourceConfigPage, DataSourcePicker, ExplorePage, GrafanaPage, Panel, PanelEditPage, PluginConfigPage, TimeRange, VariableEditPage, VariablePage, expect, isFeatureEnabled, isLegacyFeatureEnabled, test };
|
|
1564
|
+
export { AnnotationEditPage, AnnotationPage, AppConfigPage, AppPage, Components, DEFAULT_A11Y_TAGS, DashboardPage, DataSourceConfigPage, DataSourcePicker, ExplorePage, GrafanaPage, Panel, PanelEditPage, PluginConfigPage, ScopedComponent, TimeRange, VariableEditPage, VariablePage, expect, isFeatureEnabled, isLegacyFeatureEnabled, test };
|
|
1510
1565
|
export type { A11yViolationsOptions, AlertPageOptions, AlertRule, AlertRuleArgs, AlertVariant$1 as AlertVariant, AppPageNavigateOptions, AxeScanContext, ContainTextOptions, CreateDataSourceArgs, CreateDataSourcePageArgs, Credentials, Dashboard, DashboardEditViewArgs, DashboardPageArgs, DataSourceSettings, E2ESelectorGroups, FeatureFlagValue, GotoAppConfigPageArgs, GotoAppPageArgs, GrafanaPageArgs, InternalFixtures, NavigateOptions, OrgRole, PlaywrightArgs, PluginFixture, PluginOptions, PluginPageArgs, PluginTestCtx, ReadProvisionedAlertRuleArgs, ReadProvisionedDashboardArgs, ReadProvisionedDataSourceArgs, RequestOptions, TimeRangeArgs, TriggerRequestOptions, User, UserPreferences, Visualization, getByGrafanaSelectorOptions };
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var test$1 = require('@playwright/test');
|
|
4
4
|
var annotationEditPage = require('./fixtures/annotationEditPage.js');
|
|
5
|
+
var components = require('./fixtures/components.js');
|
|
5
6
|
var grafanaAPIClient = require('./fixtures/grafanaAPIClient.js');
|
|
6
7
|
var createDataSource = require('./fixtures/commands/createDataSource.js');
|
|
7
8
|
var createDataSourceConfigPage = require('./fixtures/commands/createDataSourceConfigPage.js');
|
|
@@ -43,7 +44,9 @@ var toHaveNoA11yViolations = require('./matchers/toHaveNoA11yViolations.js');
|
|
|
43
44
|
var toHaveChecked = require('./matchers/toHaveChecked.js');
|
|
44
45
|
var toHaveColor = require('./matchers/toHaveColor.js');
|
|
45
46
|
var toHavePanelErrors = require('./matchers/toHavePanelErrors.js');
|
|
47
|
+
var Components = require('./models/Components.js');
|
|
46
48
|
var DataSourcePicker = require('./models/components/DataSourcePicker.js');
|
|
49
|
+
var ScopedComponent = require('./models/components/ScopedComponent.js');
|
|
47
50
|
var Panel = require('./models/components/Panel.js');
|
|
48
51
|
var TimeRange = require('./models/components/TimeRange.js');
|
|
49
52
|
var AnnotationEditPage = require('./models/pages/AnnotationEditPage.js');
|
|
@@ -91,6 +94,7 @@ const test = testWithInternal.extend({
|
|
|
91
94
|
gotoVariablePage: gotoVariablePage.gotoVariablePage,
|
|
92
95
|
gotoAnnotationEditPage: gotoAnnotationEditPage.gotoAnnotationEditPage,
|
|
93
96
|
gotoAlertRuleEditPage: gotoAlertRuleEditPage.gotoAlertRuleEditPage,
|
|
97
|
+
components: components.components,
|
|
94
98
|
gotoDataSourceConfigPage: gotoDataSourceConfigPage.gotoDataSourceConfigPage,
|
|
95
99
|
gotoAppConfigPage: gotoAppConfigPage.gotoAppConfigPage,
|
|
96
100
|
gotoAppPage: gotoAppPage.gotoAppPage,
|
|
@@ -116,7 +120,9 @@ Object.defineProperty(exports, "selectors", {
|
|
|
116
120
|
exports.isFeatureEnabled = isFeatureToggleEnabled.isFeatureEnabled;
|
|
117
121
|
exports.isLegacyFeatureEnabled = isFeatureToggleEnabled.isLegacyFeatureEnabled;
|
|
118
122
|
exports.DEFAULT_A11Y_TAGS = scanForA11yViolations.DEFAULT_A11Y_TAGS;
|
|
123
|
+
exports.Components = Components.Components;
|
|
119
124
|
exports.DataSourcePicker = DataSourcePicker.DataSourcePicker;
|
|
125
|
+
exports.ScopedComponent = ScopedComponent.ScopedComponent;
|
|
120
126
|
exports.Panel = Panel.Panel;
|
|
121
127
|
exports.TimeRange = TimeRange.TimeRange;
|
|
122
128
|
exports.AnnotationEditPage = AnnotationEditPage.AnnotationEditPage;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var DataSourcePicker = require('./components/DataSourcePicker.js');
|
|
4
|
+
var TimeRange = require('./components/TimeRange.js');
|
|
5
|
+
|
|
6
|
+
var __defProp = Object.defineProperty;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
9
|
+
class Components {
|
|
10
|
+
constructor(ctx) {
|
|
11
|
+
__publicField(this, "dataSourcePicker");
|
|
12
|
+
__publicField(this, "timeRangePicker");
|
|
13
|
+
this.dataSourcePicker = new DataSourcePicker.DataSourcePicker(ctx);
|
|
14
|
+
this.timeRangePicker = new TimeRange.TimeRange(ctx);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
exports.Components = Components;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var semver = require('semver');
|
|
4
4
|
var test = require('@playwright/test');
|
|
5
|
-
var
|
|
5
|
+
var ScopedComponent = require('./ScopedComponent.js');
|
|
6
6
|
|
|
7
7
|
function _interopNamespaceDefault(e) {
|
|
8
8
|
var n = Object.create(null);
|
|
@@ -23,11 +23,7 @@ function _interopNamespaceDefault(e) {
|
|
|
23
23
|
|
|
24
24
|
var semver__namespace = /*#__PURE__*/_interopNamespaceDefault(semver);
|
|
25
25
|
|
|
26
|
-
class DataSourcePicker extends
|
|
27
|
-
constructor(ctx, root) {
|
|
28
|
-
super(ctx);
|
|
29
|
-
this.root = root;
|
|
30
|
-
}
|
|
26
|
+
class DataSourcePicker extends ScopedComponent.ScopedComponent {
|
|
31
27
|
/**
|
|
32
28
|
* Sets the data source picker to the provided name
|
|
33
29
|
*/
|
|
@@ -49,10 +49,10 @@ class PanelEditOptionsGroup {
|
|
|
49
49
|
return this.getFieldLocator(label).getByRole("spinbutton");
|
|
50
50
|
}
|
|
51
51
|
getSliderInput(label) {
|
|
52
|
-
if (semver.gte(this.ctx.grafanaVersion, "9.1.0")) {
|
|
52
|
+
if (semver.gte(this.ctx.grafanaVersion, "9.1.0") && semver.lt(this.ctx.grafanaVersion, "13.1.0-25389005429")) {
|
|
53
53
|
return this.getNumberInput(label);
|
|
54
54
|
}
|
|
55
|
-
return this.
|
|
55
|
+
return this.getTextInput(label);
|
|
56
56
|
}
|
|
57
57
|
getSelect(label) {
|
|
58
58
|
return new Select.Select(this.ctx, this.getFieldLocator(label));
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var GrafanaPage = require('../pages/GrafanaPage.js');
|
|
4
|
+
|
|
5
|
+
class ScopedComponent extends GrafanaPage.GrafanaPage {
|
|
6
|
+
constructor(ctx, root) {
|
|
7
|
+
super(ctx);
|
|
8
|
+
this.root = root;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Returns a new instance of this component scoped to the given root locator.
|
|
12
|
+
* Mirrors Playwright's `locator.locator(...)` chaining pattern.
|
|
13
|
+
*/
|
|
14
|
+
within(root) {
|
|
15
|
+
const Ctor = this.constructor;
|
|
16
|
+
return new Ctor(this.ctx, root);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
exports.ScopedComponent = ScopedComponent;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var semver = require('semver');
|
|
4
|
-
var
|
|
4
|
+
var ScopedComponent = require('./ScopedComponent.js');
|
|
5
5
|
|
|
6
6
|
function _interopNamespaceDefault(e) {
|
|
7
7
|
var n = Object.create(null);
|
|
@@ -22,17 +22,14 @@ function _interopNamespaceDefault(e) {
|
|
|
22
22
|
|
|
23
23
|
var semver__namespace = /*#__PURE__*/_interopNamespaceDefault(semver);
|
|
24
24
|
|
|
25
|
-
class TimeRange extends
|
|
26
|
-
constructor(ctx) {
|
|
27
|
-
super(ctx);
|
|
28
|
-
}
|
|
25
|
+
class TimeRange extends ScopedComponent.ScopedComponent {
|
|
29
26
|
/**
|
|
30
27
|
* Opens the time picker and sets the time range to the provided values
|
|
31
28
|
*/
|
|
32
29
|
async set({ from, to, zone }) {
|
|
33
30
|
const { TimeZonePicker, TimePicker, Select } = this.ctx.selectors.components;
|
|
34
31
|
try {
|
|
35
|
-
await this.getByGrafanaSelector(TimePicker.openButton).click();
|
|
32
|
+
await this.getByGrafanaSelector(TimePicker.openButton, { root: this.root }).click();
|
|
36
33
|
} catch (e) {
|
|
37
34
|
await this.ctx.page.locator('[aria-controls="TimePickerContent"]').last().click();
|
|
38
35
|
}
|
|
@@ -67,6 +67,20 @@ class DashboardPage extends GrafanaPage.GrafanaPage {
|
|
|
67
67
|
}
|
|
68
68
|
return super.navigate(url, options);
|
|
69
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Returns a locator for the dashboard toolbar area that contains the time range controls.
|
|
72
|
+
*
|
|
73
|
+
* - Grafana ≥ 11.1.0: resolves to `Dashboard.Controls` (scenes-based dashboard controls bar)
|
|
74
|
+
* - Grafana 9.4.0–11.0.x: resolves to `NavToolbar.container`
|
|
75
|
+
* - Grafana < 9.4.0: falls back to `.page-toolbar`
|
|
76
|
+
*/
|
|
77
|
+
get toolbar() {
|
|
78
|
+
const { components, pages } = this.ctx.selectors;
|
|
79
|
+
if (semver__namespace.gte(this.ctx.grafanaVersion, "11.1.0")) {
|
|
80
|
+
return this.getByGrafanaSelector(pages.Dashboard.Controls);
|
|
81
|
+
}
|
|
82
|
+
return semver__namespace.gte(this.ctx.grafanaVersion, "9.4.0") ? this.getByGrafanaSelector(components.NavToolbar.container) : this.ctx.page.locator(".page-toolbar");
|
|
83
|
+
}
|
|
70
84
|
/**
|
|
71
85
|
* Scrolls the page viewport-by-viewport to trigger below-fold panel queries.
|
|
72
86
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grafana/plugin-e2e",
|
|
3
|
-
"version": "3.7.
|
|
3
|
+
"version": "3.7.2-canary.2560.fc1fa7a.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-
|
|
52
|
+
"@grafana/e2e-selectors": "13.1.0-25644485979",
|
|
53
53
|
"semver": "^7.5.4",
|
|
54
54
|
"uuid": "^13.0.0",
|
|
55
55
|
"yaml": "^2.3.4"
|
|
56
56
|
},
|
|
57
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "fc1fa7a29f4eab23e5913db781cf191a4ab466fb"
|
|
58
58
|
}
|