Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 2ed6ca3

Browse files
authored
Extensions: e2e test usePluginComponent hook (grafana#91750)
* add simple test apps that use usePluginComponent hook and exposeComponent api * add e2e test * update readme * Update README.md * fix lint issue * pr feedback
1 parent b9cece8 commit 2ed6ca3

File tree

13 files changed

+162
-13
lines changed

13 files changed

+162
-13
lines changed

devenv/plugins.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,11 @@ apps:
1717
org_id: 1
1818
org_name: Main Org.
1919
disabled: false
20+
- type: myorg-componentconsumer-app
21+
org_id: 1
22+
org_name: Main Org.
23+
disabled: false
24+
- type: myorg-componentexposer-app
25+
org_id: 1
26+
org_name: Main Org.
27+
disabled: false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# App with exposed components
2+
3+
This directory contains two apps - `myorg-componentconsumer-app` and `myorg-componentexposer-app` which is nested inside `myorg-componentconsumer-app`.
4+
5+
`myorg-componentconsumer-app` exposes a simple React component using the [`exposeComponent`](https://grafana.com/developers/plugin-tools/reference/ui-extensions#exposecomponent) api. `myorg-componentconsumer-app` in turn, consumes this compoment using the [`https://grafana.com/developers/plugin-tools/reference/ui-extensions#useplugincomponent`](https://grafana.com/developers/plugin-tools/reference/ui-extensions#useplugincomponent) hook.
6+
7+
To test this app:
8+
9+
```sh
10+
# start e2e test instance (it will install this plugin)
11+
PORT=3000 ./scripts/grafana-server/start-server
12+
# run Playwright tests using Playwright VSCode extension or with the following script
13+
yarn e2e:playwright
14+
```
15+
16+
or
17+
18+
```
19+
PORT=3000 ./scripts/grafana-server/start-server
20+
yarn start
21+
yarn e2e
22+
```
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
define(['@grafana/data', '@grafana/runtime', 'react'], function (grafanaData, grafanaRuntime, React) {
2+
var AppPlugin = grafanaData.AppPlugin;
3+
var usePluginComponent = grafanaRuntime.usePluginComponent;
4+
5+
var MyComponent = function () {
6+
var plugin = usePluginComponent('myorg-componentexposer-app/reusable-component/v1');
7+
var TestComponent = plugin.component;
8+
var isLoading = plugin.isLoading;
9+
10+
if (!TestComponent) {
11+
return null;
12+
}
13+
14+
return React.createElement(
15+
React.Fragment,
16+
null,
17+
React.createElement('div', null, 'Exposed component:'),
18+
isLoading ? 'Loading..' : React.createElement(TestComponent, { name: 'World' })
19+
);
20+
};
21+
22+
var App = function () {
23+
return React.createElement('div', null, 'Hello Grafana!', React.createElement(MyComponent, null));
24+
};
25+
26+
var plugin = new AppPlugin().setRootPage(App);
27+
return { plugin: plugin };
28+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/grafana/grafana/main/docs/sources/developers/plugins/plugin.schema.json",
3+
"type": "app",
4+
"name": "Extensions exposed component App",
5+
"id": "myorg-componentconsumer-app",
6+
"preload": true,
7+
"info": {
8+
"keywords": ["app"],
9+
"description": "Example on how to extend grafana ui from a plugin",
10+
"author": {
11+
"name": "Myorg"
12+
},
13+
"logos": {
14+
"small": "img/logo.svg",
15+
"large": "img/logo.svg"
16+
},
17+
"screenshots": [],
18+
"version": "1.0.0",
19+
"updated": "2024-08-09"
20+
},
21+
"includes": [
22+
{
23+
"type": "page",
24+
"name": "Default",
25+
"path": "/a/myorg-componentconsumer-app",
26+
"role": "Admin",
27+
"addToNav": true,
28+
"defaultNav": true
29+
}
30+
],
31+
"dependencies": {
32+
"grafanaDependency": ">=10.3.3",
33+
"plugins": []
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
define(['@grafana/data', 'module', 'react'], function (grafanaData, amdModule, React) {
2+
const plugin = new grafanaData.AppPlugin().exposeComponent({
3+
id: 'myorg-componentexposer-app/reusable-component/v1',
4+
title: 'Reusable component',
5+
description: 'A component that can be reused by other app plugins.',
6+
component: function ({ name }) {
7+
return React.createElement('div', { 'data-testid': 'exposed-component' }, 'Hello ', name, '!');
8+
},
9+
});
10+
11+
return {
12+
plugin: plugin,
13+
};
14+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/grafana/grafana/main/docs/sources/developers/plugins/plugin.schema.json",
3+
"type": "app",
4+
"name": "A App",
5+
"id": "myorg-componentexposer-app",
6+
"preload": true,
7+
"info": {
8+
"keywords": ["app"],
9+
"description": "Will extend root app with ui extensions",
10+
"author": {
11+
"name": "Myorg"
12+
},
13+
"logos": {
14+
"small": "img/logo.svg",
15+
"large": "img/logo.svg"
16+
},
17+
"screenshots": [],
18+
"version": "%VERSION%",
19+
"updated": "%TODAY%"
20+
},
21+
"includes": [
22+
{
23+
"type": "page",
24+
"name": "Default",
25+
"path": "/a/myorg-componentexposer-app",
26+
"role": "Admin",
27+
"addToNav": false,
28+
"defaultNav": false
29+
}
30+
],
31+
"dependencies": {
32+
"grafanaDependency": ">=10.3.3",
33+
"plugins": []
34+
}
35+
}

e2e/custom-plugins/app-with-extension-point/plugin.json

+1-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,5 @@
3232
"grafanaDependency": ">=10.3.3",
3333
"plugins": []
3434
},
35-
"generated": {
36-
"extensions": []
37-
}
35+
"extensions": []
3836
}

e2e/custom-plugins/app-with-extension-point/plugins/myorg-b-app/plugin.json

+8-10
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,12 @@
3232
"grafanaDependency": ">=10.3.3",
3333
"plugins": []
3434
},
35-
"generated": {
36-
"extensions": [
37-
{
38-
"extensionPointId": "plugins/myorg-extensionpoint-app/actions",
39-
"title": "Open from B",
40-
"description": "Open a modal from plugin B",
41-
"type": "link"
42-
}
43-
]
44-
}
35+
"extensions": [
36+
{
37+
"extensionPointId": "plugins/myorg-extensionpoint-app/actions",
38+
"title": "Open from B",
39+
"description": "Open a modal from plugin B",
40+
"type": "link"
41+
}
42+
]
4543
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { test, expect } from '@grafana/plugin-e2e';
2+
3+
const pluginId = 'myorg-componentconsumer-app';
4+
const exposedComponentTestId = 'exposed-component';
5+
6+
test('should display component exposed by another app', async ({ page }) => {
7+
await page.goto(`/a/${pluginId}`);
8+
await expect(await page.getByTestId(exposedComponentTestId)).toHaveText('Hello World!');
9+
});

0 commit comments

Comments
 (0)