Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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 a 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