Skip to content
Merged
Show file tree
Hide file tree
Changes from 64 commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
10822ea
chore: move static commands list to own file
eglitise Oct 20, 2025
ed85c61
chore: pass generateCommandNotes as prop
eglitise Oct 20, 2025
00d2bfe
only show static commands list if there is no method map support
eglitise Oct 21, 2025
bf33ee8
add tab switcher for dynamic commands grid
eglitise Oct 21, 2025
a8d1b77
add UI for rendering command/method buttons
eglitise Oct 21, 2025
32b466c
filter empty values
eglitise Oct 21, 2025
ab9d03c
do not render collapses if only one available
eglitise Oct 21, 2025
800c669
also filter execute methods with no content
eglitise Oct 21, 2025
8b52c26
remove hardcoded input value types, try to detect them
eglitise Oct 21, 2025
c5105d4
convert static commands list to use a format compatible with endpoint…
eglitise Oct 22, 2025
458d6a2
store pending command in react hooks instead of redux
eglitise Oct 22, 2025
dd31ad1
dynamic execute methods are now working
eglitise Oct 23, 2025
b1534e1
dynamic commands (with matching names) are working
eglitise Oct 24, 2025
ae5a199
filter execute methods before saving them
eglitise Oct 24, 2025
7719a43
improve execute method filtering and add tests
eglitise Oct 24, 2025
ba21e42
add filtering for standard commands - full map WIP
eglitise Oct 24, 2025
6198c50
add full map of supported commands
eglitise Oct 26, 2025
13c5f8e
commands and execute methods are both working
eglitise Oct 27, 2025
c660ff4
rename property for clarity
eglitise Oct 27, 2025
5219786
extract parameters from paths for applicable commands
eglitise Oct 27, 2025
9c98e3c
add element commands to driver, to allow calling them as commands
eglitise Oct 27, 2025
dd0a38a
remove driver dependency for filterAvailableCommands
eglitise Oct 27, 2025
034a477
add unit tests for filterAvailableCommands
eglitise Oct 27, 2025
92f2b94
add support for required attribute
eglitise Oct 27, 2025
dc1d4d6
add support for deprecated attribute
eglitise Oct 27, 2025
f9a5c88
add support for info attribute
eglitise Oct 28, 2025
3e21b82
add descriptions for both tabs
eglitise Oct 28, 2025
85fbc88
move CommandResultModal to Commands component
eglitise Oct 28, 2025
c23f68a
split runCommand into two methods for clarity
eglitise Oct 28, 2025
438c5a5
store command result in react hooks instead of redux
eglitise Oct 28, 2025
9275a34
refactor MethodMapCommandsList components
eglitise Oct 28, 2025
9037ba1
add searchbar for dynamic method map
eglitise Oct 28, 2025
b6d7729
combine all commands in one list & support plugins
eglitise Oct 29, 2025
bedc75c
reduce sluggishness when entering command parameter values
eglitise Oct 29, 2025
b667447
simplify handling for special methods
eglitise Oct 29, 2025
33a9a7f
add extra handling for certain commands
eglitise Oct 30, 2025
9a6e5af
adjust tab descriptions
eglitise Oct 30, 2025
b7769d5
update deprecated command background in light mode
eglitise Oct 30, 2025
485c167
update commands documentation
eglitise Oct 30, 2025
49a979c
update types
eglitise Oct 30, 2025
965af30
run prettier
eglitise Oct 30, 2025
0c17a8e
Merge branch 'main' of https://github.com/eglitise/appium-inspector i…
eglitise Oct 30, 2025
5a0e9f8
add a few more unit tests
eglitise Oct 30, 2025
6ade34a
add extra handling for printPage
eglitise Oct 31, 2025
cd3d656
improve test for filtering out unsupported commands
eglitise Oct 31, 2025
256636d
add back stopRecordingScreen
eglitise Oct 31, 2025
0d8b32a
use a map for handling mismatching commands
eglitise Oct 31, 2025
c82006c
fix destructuring
eglitise Oct 31, 2025
b6ea676
add some memoization
eglitise Nov 1, 2025
c7e363d
add various workarounds for antd performance issues
eglitise Nov 1, 2025
8d6da97
Merge branch 'main' of github.com:eglitise/appium-inspector into dyna…
eglitise Nov 7, 2025
e77b38f
fix lint
eglitise Nov 10, 2025
dfe3def
use useRef for full command lists
eglitise Nov 10, 2025
3fd9f36
remove unneeded cancel button
eglitise Nov 10, 2025
b27168b
make parameter input smoother
eglitise Nov 10, 2025
d83f589
remove isMemo due to react compiler
eglitise Nov 10, 2025
c5c297c
speed up method filtering by avoiding dynamic toPairs calls
eglitise Nov 10, 2025
2eb3266
simplify table to row/col
eglitise Nov 10, 2025
a923353
ensure linebreaks for long method names
eglitise Nov 10, 2025
40a3c8e
fix css
eglitise Nov 10, 2025
211c27e
update translation strings
eglitise Nov 10, 2025
53f9191
update docs
eglitise Nov 10, 2025
20bed2d
handle edge case for overrides
eglitise Nov 11, 2025
32afb41
tune previous edge case handling
eglitise Nov 11, 2025
8a7d454
address copilot comments
eglitise Nov 11, 2025
67a40a8
update translation string
eglitise Nov 12, 2025
9f25783
define local constants for method names
eglitise Nov 12, 2025
b6641e5
address comments in Commands component
eglitise Nov 12, 2025
19441d0
address comments in commands tab utils
eglitise Nov 12, 2025
598cb90
address comments in commands unit test file
eglitise Nov 12, 2025
c45b033
label args for executeScript as optional
eglitise Nov 12, 2025
6b7456e
address comments
eglitise Nov 13, 2025
670fdc9
update docs image due to updated texts
eglitise Nov 13, 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/common/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -320,5 +320,9 @@
"toggleTableFormatting": "Toggle Table Formatting",
"copyResultToClipboard": "Copy Result to Clipboard",
"Property": "Property",
"noCapsFound": "No session capabilities found. Please use the Capability Builder to edit, add, and save your capability set. Refer to the tutorial at {{url}}"
"noCapsFound": "No session capabilities found. Please use the Capability Builder to edit, add, and save your capability set. Refer to the tutorial at {{url}}",
"executeMethods": "Execute Methods",
"dynamicCommandsDescription": "Run commands supported by the currently active driver and plugin(s). Note that certain commands may only work in certain contexts. Any commands not supported by WebdriverIO are not shown in this list.",
"dynamicExecuteMethodsDescription": "Run any execute method supported by the currently active driver and plugin(s).",
"methodDeprecated": "This method is deprecated"
}
68 changes: 25 additions & 43 deletions app/common/renderer/actions/SessionInspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,6 @@ export const HIDE_PROMPT_KEEP_ALIVE = 'HIDE_PROMPT_KEEP_ALIVE';

export const SELECT_INSPECTOR_TAB = 'SELECT_INSPECTOR_TAB';

export const ENTERING_COMMAND_ARGS = 'ENTERING_COMMAND_ARGS';
export const CANCEL_PENDING_COMMAND = 'CANCEL_PENDING_COMMAND';
export const SET_COMMAND_ARG = 'SET_COMMAND_ARG';

export const SET_CONTEXT = 'SET_CONTEXT';

export const SET_APP_ID = 'SET_APP_ID';
Expand All @@ -95,8 +91,6 @@ export const SET_KEEP_ALIVE_INTERVAL = 'SET_KEEP_ALIVE_INTERVAL';
export const SET_USER_WAIT_TIMEOUT = 'SET_USER_WAIT_TIMEOUT';
export const SET_LAST_ACTIVE_MOMENT = 'SET_LAST_ACTIVE_MOMENT';

export const SET_VISIBLE_COMMAND_RESULT = 'SET_VISIBLE_COMMAND_RESULT';

export const SET_AWAITING_MJPEG_STREAM = 'SET_AWAITING_MJPEG_STREAM';

export const SHOW_GESTURE_EDITOR = 'SHOW_GESTURE_EDITOR';
Expand Down Expand Up @@ -343,7 +337,7 @@ export function restartSession(error, params) {
});
const quitSes = quitSession('Window closed');
const newSes = newSession(getState().builder.caps);
const getPageSrc = applyClientMethod({methodName: 'getPageSource', ignoreResult: true});
const getPageSrc = applyClientMethod({methodName: 'getPageSource'});
const storeSessionSet = storeSessionSettings();
const getSavedClientFrame = getSavedClientFramework();
const runKeepAliveLp = runKeepAliveLoop();
Expand Down Expand Up @@ -458,7 +452,6 @@ export function storeSessionSettings(updatedSessionSettings = null) {
const action = applyClientMethod({
methodName: 'getSettings',
skipRefresh: true,
ignoreResult: true,
});
sessionSettings = await action(dispatch, getState);
}
Expand Down Expand Up @@ -587,7 +580,6 @@ export function setLocatorTestElement(elementId) {
methodName: 'getElementRect',
skipRefresh: true,
skipRecord: true,
ignoreResult: true,
});
const {commandRes} = await action(dispatch, getState);
dispatch({
Expand Down Expand Up @@ -824,21 +816,23 @@ export function selectInspectorTab(interaction) {
};
}

export function startEnteringCommandArgs(commandName, command) {
return (dispatch) => {
dispatch({type: ENTERING_COMMAND_ARGS, commandName, command});
};
}

export function cancelPendingCommand() {
return (dispatch) => {
dispatch({type: CANCEL_PENDING_COMMAND});
};
}
export function getSupportedSessionMethods() {
return async (_dispatch, getState) => {
async function safelyCallCommand(methodName) {
try {
const action = executeDriverCommand({methodName});
const {commandRes} = await action(getState);
return commandRes;
} catch {
return [];
}
}

export function setCommandArg(index, value) {
return (dispatch) => {
dispatch({type: SET_COMMAND_ARG, index, value});
const [commands, executeMethods] = await Promise.all([
safelyCallCommand('getAppiumCommands'),
safelyCallCommand('getAppiumExtensions'),
]);
return {commands, executeMethods};
};
}

Expand Down Expand Up @@ -907,7 +901,6 @@ export function callClientMethod(params) {
return async (dispatch, getState) => {
const {driver, appMode, isUsingMjpegMode, isSourceRefreshOn, autoSessionRestart} =
getState().inspector;
const {methodName, ignoreResult = true} = params;
params.appMode = appMode;
params.autoSessionRestart = autoSessionRestart;

Expand All @@ -927,22 +920,6 @@ export function callClientMethod(params) {
action(dispatch, getState);
const inspectorDriver = InspectorDriver.instance(driver);
const res = await inspectorDriver.run(params);
let {commandRes} = res;

// Ignore empty objects
if (_.isObject(res) && _.isEmpty(res)) {
commandRes = null;
}

if (!ignoreResult) {
// if the user is running actions manually, we want to show the full response with the
// ability to scroll etc...
const result = JSON.stringify(commandRes, null, ' ');
const truncatedResult = _.truncate(result, {length: 2000});
log.info(`Result of client command was:`);
log.info(truncatedResult);
setVisibleCommandResult(result, methodName)(dispatch);
}
res.elementId = res.id;
return res;
} catch (error) {
Expand All @@ -957,9 +934,14 @@ export function callClientMethod(params) {
};
}

export function setVisibleCommandResult(result, methodName) {
return (dispatch) => {
dispatch({type: SET_VISIBLE_COMMAND_RESULT, result, methodName});
// Simple alternative to callClientMethod, for when we only want to
// run the command without any side-effects
export function executeDriverCommand(params) {
return async (getState) => {
const {driver} = getState().inspector;
params.skipRefresh = true;
const inspectorDriver = InspectorDriver.instance(driver);
return await inspectorDriver.run(params);
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ const CommandResultRawTable = ({result}) => {
};

const CommandResultModalFooter = ({
visibleCommandResult,
commandResult,
closeCommandModal,
setFormatResult,
formatResult,
Expand All @@ -195,7 +195,7 @@ const CommandResultModalFooter = ({
<Button
icon={<CopyOutlined />}
disabled={formatResult}
onClick={() => copyToClipboard(visibleCommandResult)}
onClick={() => copyToClipboard(commandResult)}
/>
</Tooltip>
</Space>
Expand All @@ -208,31 +208,26 @@ const CommandResultModalFooter = ({
</Row>
);

const CommandResultModal = ({
visibleCommandMethod,
visibleCommandResult,
setVisibleCommandResult,
t,
}) => {
const CommandResultModal = ({commandName, commandResult, clearCurrentCommand, t}) => {
const [formatResult, setFormatResult] = useState(false);

const {parsedResult, isPrimitive} = parseCommandResult(visibleCommandResult);
const {parsedResult, isPrimitive} = parseCommandResult(commandResult);

const closeCommandModal = () => {
setVisibleCommandResult(null);
clearCurrentCommand();
setFormatResult(false);
};

return (
<Modal
title={t('methodCallResult', {methodName: visibleCommandMethod})}
open={!!visibleCommandResult}
title={t('methodCallResult', {methodName: commandName})}
open={!!commandResult}
onCancel={() => closeCommandModal()}
width={{md: '80%', lg: '70%', xl: '60%', xxl: '50%'}}
className={styles.commandResultModal}
footer={
<CommandResultModalFooter
visibleCommandResult={visibleCommandResult}
commandResult={commandResult}
closeCommandModal={closeCommandModal}
setFormatResult={setFormatResult}
formatResult={formatResult}
Expand All @@ -244,7 +239,7 @@ const CommandResultModal = ({
{formatResult ? (
<CommandResultFormattedTable result={parsedResult} isPrimitive={isPrimitive} t={t} />
) : (
<CommandResultRawTable result={visibleCommandResult} />
<CommandResultRawTable result={commandResult} />
)}
</Modal>
);
Expand Down
Loading
Loading