Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions examples/android-gmail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Using appium generate test tool create automation test for below step

Steps:
1. Open Gmail app
2. Compose a email to [email protected] with subject "Test email from appium"
3. Add body as "Hello World!"
4. and send
9 changes: 9 additions & 0 deletions examples/android-todo-app.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Using appium generate test tool create automation test for below step

STEPS:
1. Open TODO app
2. Add a todo list with Title "Complete appium mcp server"
3. Use June 25 2025 as date
4. Add it to personal list

Use JAVA + Testng for test generation
158 changes: 141 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"jest": "^29.7.0",
"prettier": "^3.5.3",
"ts-jest": "^29.1.2",
"ts-node": "^10.9.2",
"typescript": "^5.8.3"
}
}
}
2 changes: 1 addition & 1 deletion src/locators/locator-generation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ export function getSuggestedLocators(
}
}

return sortedLocators;
return [sortedLocators[0]];
}

/**
Expand Down
5 changes: 5 additions & 0 deletions src/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { z } from 'zod';

export const elementUUIDScheme = z
.string()
.describe('The uuid of the element returned by appium_find_element to click');
50 changes: 50 additions & 0 deletions src/tools/generate-tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { FastMCP } from 'fastmcp/dist/FastMCP.js';
import { z } from 'zod';

export default function generateTest(server: FastMCP): void {
const generateTestSchema = z.object({
steps: z.array(z.string()).describe('The steps of the test'),
});

const instructions = (params: { steps: string[] }) =>
[
`## Instructions`,
`- You are an Appium test generator.`,
`- You are given a scenario and you need to generate a appium test for it.`,
`- Request user to select the platform first using select_platform tool and create a session`,
`- Use generate_locators tool to fetch all interactable elements from the current screen and use it to generate the tests`,
`- Element can only be clicked only if it is clickable.`,
`- Text can entered in the element only if it is focusable`,
`- If any interaction on element is failed, retry again with a differnt possible locator in the hierrarchy`,
`- Interact with the app using the tools provided and generate the test`,
'- DO NOT generate test code based on the scenario alone. DO run steps one by one using the tools provided instead.',
'- Only after all steps are completed, emit a Appium test based on message history',
'- Save generated test file in the tests directory',
`- Use generate://code-with-locators resource as reference for code generation`,
`- Always call find_element_tool to retrieve the element UUID before interacting with the element`,
`Steps:`,
...params.steps.map((step, index) => `- ${index + 1}. ${step}`),
].join('\n');

server.addTool({
name: 'appium_generate_tests',
description: 'Generate tests for a given mobile app',
parameters: generateTestSchema,
annotations: {
readOnlyHint: false,
openWorldHint: false,
},
execute: async (args: any, context: any): Promise<any> => {
return {
content: [
{
type: 'text',
text: instructions({
steps: args.steps,
}),
},
],
};
},
});
}
17 changes: 16 additions & 1 deletion src/tools/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
import { FastMCP } from 'fastmcp/dist/FastMCP.js';
import createSession from './create-session.js';
import generateLocators from './locators.js';
import selectPlatform from './select-platform.js';
import generateTest from './generate-tests.js';
import findElement from './interactions/find.js';
import clickElement from './interactions/click.js';
import setValue from './interactions/setValue.js';
import getText from './interactions/getText.js';
import screenshot from './interactions/screenshot.js';

export default function registerTools(server: any): void {
export default function registerTools(server: FastMCP): void {
selectPlatform(server);
createSession(server);
generateLocators(server);

findElement(server);
clickElement(server);
setValue(server);
getText(server);
screenshot(server);

generateTest(server);
console.log('All tools registered');
}
Loading