Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: enable appium-inspector as an appium plugin #1878

Merged
merged 60 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from 57 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
3ce0cfd
Update package.yml
KazuCocoa Nov 6, 2024
0764820
use secrets
KazuCocoa Nov 6, 2024
bc95a0a
apply Prettier
KazuCocoa Nov 6, 2024
f37a521
ci: add github token and changes to always
KazuCocoa Nov 6, 2024
afa3bf8
prototype for plugin
KazuCocoa Dec 10, 2024
9e514c0
Merge branch 'main' into proto-plugin
KazuCocoa Dec 10, 2024
5d42e24
update lock
KazuCocoa Dec 10, 2024
1b812da
add js
KazuCocoa Dec 10, 2024
01a2652
add js
KazuCocoa Dec 10, 2024
b897b2e
simplify
KazuCocoa Dec 11, 2024
090f50f
simplify more
KazuCocoa Dec 11, 2024
d92a944
Merge branch 'main' into proto-plugin
KazuCocoa Dec 11, 2024
659d9b7
create package.json in plugins
KazuCocoa Dec 11, 2024
30c634b
adjust
KazuCocoa Dec 11, 2024
bfdc8e1
add comment
KazuCocoa Dec 11, 2024
5b40a50
remove reps as no usage
KazuCocoa Dec 11, 2024
a994da9
revert lock on the top
KazuCocoa Dec 11, 2024
fb89cf2
revert lock on the top
KazuCocoa Dec 11, 2024
231bbc0
Merge branch 'main' into proto-plugin
KazuCocoa Dec 11, 2024
3b5fa7d
add files
KazuCocoa Dec 11, 2024
b9a371b
add comment how to run with source=local
KazuCocoa Dec 11, 2024
5469ea3
add -plugin in the name
KazuCocoa Dec 11, 2024
4c53dab
Merge branch 'main' into proto-plugin
KazuCocoa Dec 27, 2024
cb25743
make inspector as appium plugin (#1867)
saikrishna321 Dec 27, 2024
dcf4f63
Merge branch 'main' into proto-plugin
KazuCocoa Dec 27, 2024
1c3edc0
apply format and lint
KazuCocoa Dec 28, 2024
86e7006
update proto-plugin branch (#1871)
KazuCocoa Dec 28, 2024
4d2f828
chore: tweak the path names
KazuCocoa Dec 28, 2024
5248688
docs: add a brief readme
KazuCocoa Dec 28, 2024
a4d14c6
apply prettier
KazuCocoa Dec 28, 2024
c0934ab
Merge branch 'proto-plugin' of github.com:appium/appium-inspector int…
KazuCocoa Dec 28, 2024
4ed1bd3
add const
KazuCocoa Dec 28, 2024
9b84563
chore: adjust routes and fix root behavior (#1873)
KazuCocoa Dec 29, 2024
c67908c
updated readme for plugin (#1874)
saikrishna321 Dec 29, 2024
cbb53d0
simplified the build:plugin and add clean:plugin
KazuCocoa Dec 30, 2024
9f56ed5
fix readme format
saikrishna321 Dec 30, 2024
b1eb482
address review comments - partial
saikrishna321 Dec 31, 2024
972545a
remove unnecessary deps and add lint disabler
KazuCocoa Dec 31, 2024
c5fb734
add dev and license
KazuCocoa Dec 31, 2024
5f5df23
add version sync script
KazuCocoa Dec 31, 2024
abe014b
apply lint and prettier
KazuCocoa Dec 31, 2024
33748b8
add release in README and TODO for followup PR
KazuCocoa Dec 31, 2024
94ec121
tweak the script
KazuCocoa Dec 31, 2024
b355207
use resolve and fs/promises
KazuCocoa Jan 1, 2025
cb79ed3
simplified a bit
KazuCocoa Jan 1, 2025
3db1202
use mjs instead of js
KazuCocoa Jan 1, 2025
0ec99fa
add mjs file
KazuCocoa Jan 1, 2025
fa48100
modify readme
KazuCocoa Jan 1, 2025
a42007f
sync more basic info
KazuCocoa Jan 1, 2025
5596c40
Merge branch 'main' into appium-inspector-plugin
KazuCocoa Jan 1, 2025
0e11407
add new line
KazuCocoa Jan 2, 2025
53fefc4
add node:
KazuCocoa Jan 2, 2025
5916dcc
Merge branch 'appium-inspector-plugin' of github.com:appium/appium-in…
KazuCocoa Jan 2, 2025
a2f53a8
address npm run build:plugin as well
KazuCocoa Jan 2, 2025
8daadd0
remvoe npm installation for now
KazuCocoa Jan 2, 2025
352f9a3
fix reviews in code
KazuCocoa Jan 2, 2025
f736397
adjust locale with vite base
KazuCocoa Jan 2, 2025
5ea336f
use trimEnd in lodash
KazuCocoa Jan 3, 2025
dcaace4
fix wrong key
KazuCocoa Jan 3, 2025
158b537
fix return
KazuCocoa Jan 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion app/web/polyfills.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ import i18NextBackend from 'i18next-chained-backend';
import HttpApi from 'i18next-http-backend';
import LocalStorageBackend from 'i18next-localstorage-backend';

// Adjust locales path depending on Vite base (web vs plugin)
const viteBase = import.meta.env.BASE_URL;
const vitePath = viteBase.endsWith('/') ? viteBase : `${viteBase}/`;
mykola-mokhnach marked this conversation as resolved.
Show resolved Hide resolved

const localesPath =
process.env.NODE_ENV === 'development'
? '/locales' // 'public' folder contents are served at '/'
: '../locales'; // from 'dist-browser/assets/'
: `..${vitePath}locales`; // from 'dist-browser/assets/'

const i18NextBackendOptions = {
backends: [LocalStorageBackend, HttpApi],
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,19 @@
"build": "npm run build:browser && npm run build:electron",
"build:browser": "vite build",
"build:browser:url": "vite build --base $PUBLIC_URL",
"build:plugin": "vite build --base /inspector --outDir ../../plugins/dist-browser",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should it be a part of the common build script?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to include this in build after completing npm publish work as well, so yes but not yet in this PR.

"build:electron": "electron-vite build",
"preview:browser": "npm run build:browser && vite preview",
"preview:electron": "electron-vite preview",
"pack:electron": "electron-builder build --publish never",
"clean": "npm run clean:electron && npm run clean:browser && npm run clean:npm",
"clean:electron": "rimraf dist/ && rimraf node_modules/.vite/ && rimraf node_modules/.vite-electron-renderer/",
"clean:browser": "rimraf dist-browser/ && rimraf node_modules/.vite/",
"clean:plugin": "rimraf plugins/dist-browser",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

"clean:npm": "rimraf package-lock.json && rimraf node_modules && npm install",
"build:docs": "appium-docs build",
"dev:docs": "appium-docs build --serve",
"plugin:sync:version": "node ./scripts/sync-plugin.mjs",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

"publish:docs": "appium-docs build --deploy --push -b docs-site -m 'docs: build docs for appium-inspector@%s' --alias latest",
"install-docs-deps": "appium-docs init --no-mkdocs",
"postversion": "git pull --tags && git push && git push --tags",
Expand Down
54 changes: 54 additions & 0 deletions plugins/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Appium Inspector Plugin

A plugin that integrates the [Appium Inspector](https://github.com/appium/appium-inspector) directly into your Appium server installation, providing a web-based interface for inspecting and interacting with your application under test.

## Features

- Web-based Appium Inspector interface accessible via `/inspector` endpoint with appium server
- Full feature parity with standalone Appium Inspector

## Installation

Install the plugin using one of the following methods:

```bash
# Install from local directory. Then, please run 'npm run build:plugin' as well.
appium plugin install --source=local /path/to/appium-inspector/plugins
```

> [!Note]
> Appium 3 will support this plugin as a first-class plugin with `appium plugin install inspector`

## Usage

1. Start Appium server with the inspector plugin enabled:

```bash
appium --use-plugins=inspector --allow-cors
```

2. Access the Inspector interface by navigating to:

```
http://localhost:4723/inspector
```

## Development

1. `git clone` this repositiry
2. `appium plugin install --source=local /path/to/appium-inspector/plugins`
3. Update the plugin content with `npm run build:plugin` in `/path/to/appium-inspector`
4. Start Appium with `appium --use-plugins=inspector --allow-cors`

This plugin only needs the `appium` server as a `peerDependencies`.

## Release

(TODO: add this release steps in .github/workflows/package.yml later as another PR)

1. Run `npm run plugin:sync:version` to sync the version with the root project.json
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say this script should be executed automatically as soon as we bump the version of the main project via npm version

Copy link
Member Author

@KazuCocoa KazuCocoa Jan 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. It will be a follow-up PR to treat npm publish stuff in my current plan.

2. Run `npm publish` in `/path/to/appium-inspector/plugins` to publish the module

## License

[Apache-2.0](https://github.com/appium/appium-inspector/blob/main/LICENSE)
44 changes: 44 additions & 0 deletions plugins/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import path from 'node:path';
import {fileURLToPath} from 'node:url';

import {BasePlugin} from 'appium/plugin.js';
const PLUGIN_ROOT_PATH = '/inspector';
const INDEX_HTML = 'index.html';
const ROOT_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), 'dist-browser');

/**
* Appium Inspector Plugin class
* @extends {BasePlugin}
*/
export class AppiumInspectorPlugin extends BasePlugin {
/**
* Creates an instance of AppiumInspectorPlugin
* @param {string} name - The name of the plugin
* @param {Record<string, unknown>} cliArgs - Command line arguments
*/
constructor(name, cliArgs) {
super(name, cliArgs);
}

/**
* Handles inspector page requests
* @param {import('express').Request} req - Express request object
* @param {import('express').Response} res - Express response object
* @returns {Promise<void>}
*/
static async openInspector(req, res) {
const reqPath =
req.path === PLUGIN_ROOT_PATH ? INDEX_HTML : req.path.substring(PLUGIN_ROOT_PATH.length);
res.sendFile(reqPath, {root: ROOT_DIR});
}

/**
* Updates the Express server configuration
* @param {import('express').Application} expressApp - Express application instance
* @returns {Promise<void>}
*/
static async updateServer(expressApp) {
// Handle both /inspector and /inspector/* paths
expressApp.all(['/inspector', '/inspector/*'], AppiumInspectorPlugin.openInspector);
}
}
47 changes: 47 additions & 0 deletions plugins/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "appium-inspector-plugin",
"version": "2024.12.1",
"description": "An app inspector for use with an Appium server",
"repository": {
"type": "git",
"url": "git+https://github.com/appium/appium-inspector.git"
},
"author": {
"name": "Appium Developers",
"url": "https://github.com/appium"
},
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/appium/appium-inspector/issues"
},
"keywords": [
"appium"
],
"homepage": "https://github.com/appium/appium-inspector",
"main": "index.mjs",
"type": "module",
"exports": {
".": {
"import": "./index.mjs"
}
},
"peerDependencies": {
"appium": "^2.0.0"
},
"files": [
"index.mjs",
"package.json",
"dist-browser",
"README.md"
],
"dependencies": {},
"devDependencies": {},
"engines": {
"node": ">=20.x",
"npm": ">=10.x"
},
"appium": {
"pluginName": "inspector",
"mainClass": "AppiumInspectorPlugin"
}
}
48 changes: 48 additions & 0 deletions scripts/sync-plugin.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import fs from 'node:fs/promises';
import path from 'node:path';
import {fileURLToPath} from 'node:url';

const PROJECT_ROOT = path.dirname(fileURLToPath(import.meta.url));
const ROOT_PKG_JSON_PATH = path.resolve(PROJECT_ROOT, '..', 'package.json');
const PLUGIN_PKG_JSON_PATH = path.resolve(PROJECT_ROOT, '..', 'plugins', 'package.json');

const SYNC_PACKAGE_KEYS = [
// To update ever version release
'version',

// These basic information should be the same with the top package.json
'engines',
'license',
'repository',
'author',
'bugs',
'homepage',
];

/**
* Return JSON parsed contents from the given path.
* @param {string} path
* @returns {Promise<object>}
*/
async function readJsonContent(jsonPath) {
return await JSON.parse(await fs.readFile(jsonPath, 'utf8'));
mykola-mokhnach marked this conversation as resolved.
Show resolved Hide resolved
}

async function main() {
const [rootJsonContent, pluginJsonContent] = await Promise.all(
[ROOT_PKG_JSON_PATH, PLUGIN_PKG_JSON_PATH].map(readJsonContent),
);

for (const key in SYNC_PACKAGE_KEYS) {
pluginJsonContent[key] = rootJsonContent[key];
}

// The new line in the last is to avoid prettier error.
await fs.writeFile(
PLUGIN_PKG_JSON_PATH,
`${JSON.stringify(pluginJsonContent, null, 2)}\n`,
'utf8',
);
}

(async () => await main())();
Loading