Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork158
feat(mcp): introducing Serenity/JS MCP server#2912
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Open
jan-molak wants to merge64 commits intomainChoose a base branch fromfeatures/mcp
base:main
Could not load branches
Branch not found:{{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline, and old review comments may become outdated.
Uh oh!
There was an error while loading.Please reload this page.
Open
Changes from54 commits
Commits
Show all changes
64 commits Select commitHold shift + click to select a range
0ee9abe feat(mcp): first draft of the Serenity/JS MCP server
jan-molak3c0877f chore(mcp): corrected build script
jan-molak594f077 chore(deps): updated pnpm
jan-molak31c88eb chore(deps): corrected cc script
jan-molak1036c41 feat(mcp): support for Navigate interactions
jan-molak09b836a fix(mcp): corrected the shutdown hook
jan-molak5b8ec87 fix(mcp): corrected the input schema definition
jan-molak7e4a641 Merge branch 'main' into features/mcp
jan-molak3e424ee chore(mcp): version bump
jan-molakfca2cda chore(deps): updated playwright
jan-molakd26083c Merge branch 'main' into features/mcp
jan-molakf63ebef Merge branch 'main' into features/mcp
jan-molak6fea805 feat(core): internal ModuleLoader supports importing ESM modules
jan-molak1ad6675 feat(mcp): new MCP server architecture
jan-molak289c3c1 fix(core): corrected module loader behaviour for CJS modules
jan-molakd65a272 test(mcp): corrected configuration
jan-molaka330ed6 Merge branch 'main' into features/mcp
jan-molake06a946 Merge branch 'main' into features/mcp
jan-molak6ae5009 chore(mcp): version bump
jan-molakd7308fb chore(deps): updated playwright
jan-molak6ebeb83 chore(deps): updated playwright
jan-molakf011176 feat(mcp): moved test automation capabilities to a dedicated section …
jan-molak7e3098e test(mcp): cleaned up the test directory structure
jan-molak807392c fix(mcp): clarified the purpose of the descriptor
jan-molakb238656 refactor(mcp): refactored the ListCapabilitiesController
jan-molak4a91abc refactor(mcp): improved naming in the output schema of the ListCapabi…
jan-molak176e2bf fix(mcp): first draft of project-related MCP capabilities
jan-molakf0e77a1 Merge branch 'main' into features/mcp
jan-molak4d77310 feat(mcp): support for configuring Playwright Test to use Serenity/JS
jan-molak28ff81c feat(mcp): capability to suggest package.json scripts for running Ser…
jan-molak78e6550 feat(mcp): capability to generate an example test file
jan-molak89b2732 fix(mcp): corrected typos in the template
jan-molakca36c0a test(mcp): cleaned up the directory structure
jan-molak6cdf812 fix(mcp): finished the prototype
jan-molaka30c855 Merge branch 'main' into features/mcp
jan-molak078ddb8 chore(deps): bumped version
jan-molakc60c467 test(mcp): updated tests
jan-molakb6112fe fix(mcp): detect env variables
jan-molakfcc114e refactor(mcp): improved description
jan-molak1530e1f fix(mcp): added instructions on running tests
jan-molakb12b138 fix(mcp): optimised the instructions
jan-molak1d54486 fix(mcp): optimised the response from environment detector
jan-molak50dcc05 refactor(mcp): cleaned up env vars section
jan-molakb0d03dc refactor(mcp): new MCP framework
jan-molak3078d73 refactor(mcp): refactored the package structure
jan-molak63d736c refactor(mcp): implemented a replacement MCP server
jan-molak03355d9 test(mcp): refactored the examples structure
jan-molak9161e64 refactor(mcp): made actors an integral part of the MCP server
jan-molakfce6e44 refactor(mcp): migrated the project_analyze_tool to the new pattern
jan-molakd889c34 feat(mcp): finished the project analyzer tool
jan-molak8445409 feat(mcp): implemented the install_dependencies tool
jan-molak2af4222 Merge branch 'main' into features/mcp
jan-molaka4ed425 feat(mcp): project analyze tool now detects the test runner
jan-molak4297cf8 refactor(mcp): complain if no test runner is found when analysing the…
jan-molakf66e7ad fix(mcp): improved error handling in scenarios where test runner is n…
jan-molak6ba4b77 feat(mcp): dependency installation and package.json configuration tools
jan-molak18966c4 style(mcp): code clean-up
jan-molak9bcbe16 Merge branch 'main' into features/mcp
jan-molak2dd3ddd Merge branch 'main' into features/mcp
jan-molak6415a6c chore(mcp): version bump
jan-molaka99fc82 Merge branch 'main' into features/mcp
jan-molakd2df8c9 feat(mcp): configure test runner tool
jan-molak5dfe6e0 Merge branch 'main' into features/mcp
jan-molaka5fd90c Merge branch 'main' into features/mcp
jan-molakFile filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
1 change: 1 addition & 0 deletions.github/workflows/main.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -147,6 +147,7 @@ jobs: | ||
| strategy: | ||
| matrix: | ||
| module: | ||
| - mcp | ||
| - playwright-test | ||
| - playwright-test-ct | ||
| - playwright-web | ||
15 changes: 0 additions & 15 deletionsexamples/webdriverio-cucumber/todo.md
This file was deleted.
Oops, something went wrong.
Uh oh!
There was an error while loading.Please reload this page.
8 changes: 4 additions & 4 deletionsintegration/jasmine/spec/screenplay.spec.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletionsintegration/mcp/.gitignore
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # Node | ||
| node_modules | ||
| *.log | ||
| # Build artifacts | ||
| lib | ||
| playwright-report | ||
| test-results | ||
| output |
7 changes: 7 additions & 0 deletionsintegration/mcp/examples/empty/package.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "name": "@integration/mcp-examples-empty", | ||
| "private": true, | ||
| "config": { | ||
| "access": "private" | ||
| } | ||
| } |
7 changes: 7 additions & 0 deletionsintegration/mcp/examples/package-json-empty-scripts/package.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "name": "example-package-json-empty-scripts", | ||
| "version": "1.0.0", | ||
| "main": "index.js", | ||
| "scripts": {}, | ||
| "description": "" | ||
| } |
6 changes: 6 additions & 0 deletionsintegration/mcp/examples/package-json-no-scripts/package.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| { | ||
| "name": "example-package-json-no-scripts", | ||
| "version": "1.0.0", | ||
| "main": "index.js", | ||
| "description": "" | ||
| } |
25 changes: 25 additions & 0 deletionsintegration/mcp/examples/playwright-test-default-config/playwright.config.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import { defineConfig, devices } from '@playwright/test'; | ||
| /** | ||
| * See https://playwright.dev/docs/test-configuration. | ||
| */ | ||
| export default defineConfig({ | ||
| testDir: './tests', | ||
| /* Run tests in files in parallel */ | ||
| fullyParallel: true, | ||
| /* Fail the build on CI if you accidentally left test.only in the source code. */ | ||
| forbidOnly: !!process.env.CI, | ||
| /* Retry on CI only */ | ||
| retries: process.env.CI ? 2 : 0, | ||
| /* Opt out of parallel tests on CI. */ | ||
| workers: process.env.CI ? 1 : undefined, | ||
| /* Reporter to use. See https://playwright.dev/docs/test-reporters */ | ||
| reporter: 'html', | ||
| /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ | ||
| use: { | ||
| // baseURL: 'http://localhost:3000', | ||
| }, | ||
| /* Configure projects for major browsers */ | ||
| projects: [ | ||
| { name: 'chromium', use: { ...devices['Desktop Chrome'] } }, | ||
| ], | ||
| }); |
11 changes: 11 additions & 0 deletionsintegration/mcp/examples/playwright-test/package.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "name": "@integration/mcp-examples-playwright-test", | ||
| "private": true, | ||
| "config": { | ||
| "access": "private" | ||
| }, | ||
| "devDependencies": { | ||
| "@playwright/test": "^1.55.1", | ||
| "@types/node": "^24.3.0" | ||
| } | ||
| } |
45 changes: 45 additions & 0 deletionsintegration/mcp/package.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| { | ||
| "name": "@integration/mcp", | ||
| "version": "3.0.0", | ||
| "description": "Serenity/JS MCP integration tests", | ||
| "type": "module", | ||
| "author": { | ||
| "name": "Jan Molak", | ||
| "email": "jan.molak@smartcodeltd.co.uk", | ||
| "url": "https://janmolak.com" | ||
| }, | ||
| "homepage": "https://serenity-js.org", | ||
| "license": "Apache-2.0", | ||
| "private": true, | ||
| "config": { | ||
| "access": "private" | ||
| }, | ||
| "scripts": { | ||
| "clean": "rimraf playwright-report playwright/.cache", | ||
| "test": "playwright test --config playwright.config.ts", | ||
| "inspector": "mcp-inspector npx mcp-server-serenity-js" | ||
| }, | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "https://github.com/serenity-js/serenity-js.git" | ||
| }, | ||
| "bugs": { | ||
| "url": "https://github.com/serenity-js/serenity-js/issues" | ||
| }, | ||
| "engines": { | ||
| "node": "^18.12 || ^20 || ^22" | ||
| }, | ||
| "dependencies": { | ||
| "@integration/testing-tools": "workspace:*", | ||
| "@modelcontextprotocol/inspector": "0.16.8", | ||
| "@modelcontextprotocol/sdk": "1.18.2", | ||
| "@playwright/test": "1.55.1", | ||
| "@serenity-js/core": "workspace:*", | ||
| "@serenity-js/mcp": "workspace:*", | ||
| "@serenity-js/playwright": "workspace:*", | ||
| "@serenity-js/playwright-test": "workspace:*", | ||
| "c8": "10.1.3", | ||
| "tailwindcss": "3.4.17", | ||
| "typescript": "5.8.3" | ||
| } | ||
| } |
18 changes: 18 additions & 0 deletionsintegration/mcp/playwright.config.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import { defineConfig } from '@playwright/test'; | ||
| import type { TestOptions } from './src/mcp-api.js'; | ||
| export default defineConfig<TestOptions>({ | ||
| testDir: './spec', | ||
| fullyParallel: true, | ||
| forbidOnly: !!process.env.CI, | ||
| retries: process.env.CI ? 2 : 0, | ||
| workers: process.env.CI ? 1 : undefined, | ||
| reporter: 'list', | ||
| projects: [ | ||
| // { name: 'msedge', use: { mcpBrowser: 'msedge' } }, | ||
| { name: 'chromium', use: { mcpBrowser: 'chromium' } }, | ||
| // { name: 'firefox', use: { mcpBrowser: 'firefox' } }, | ||
| // { name: 'webkit', use: { mcpBrowser: 'webkit' } }, | ||
| ], | ||
| }); |
29 changes: 29 additions & 0 deletionsintegration/mcp/spec/assertions/expectations.spec.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| import { describe, expect, it } from '../../src/mcp-api.js'; | ||
| describe('expectations', () => { | ||
| it('produces an expectation to include a substring', async ({ client, testServerUrl }) => { | ||
| const response = await client.callTool({ | ||
| name: 'serenity_assertions_includes', | ||
| arguments: { | ||
| actorName: 'Alice', | ||
| expected: { | ||
| imports: { '@serenity-js/web': [ 'Text', 'PageElement', 'By' ] }, | ||
| question: `Text.of(PageElement.located(By.css('h1')).describedAs('header'))`, | ||
| }, | ||
| }, | ||
| }); | ||
| expect(response.structuredContent).toEqual({ | ||
| result: { | ||
| question: { | ||
| imports: { | ||
| '@serenity-js/assertions': [ 'includes' ], | ||
| '@serenity-js/web': [ 'By', 'PageElement', 'Text' ] | ||
| }, | ||
| template: "includes(Text.of(PageElement.located(By.css('h1')).describedAs('header')))" | ||
| }, | ||
| } | ||
| }); | ||
| }); | ||
| }); |
63 changes: 63 additions & 0 deletionsintegration/mcp/spec/list_capabilities.spec.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| import { describe, expect, it } from '../src/mcp-api.js'; | ||
| describe('List Capabilities', () => { | ||
| it('lists Serenity/JS test automation capabilities', async ({ client }) => { | ||
| const response = await client.callTool({ | ||
| name: 'serenity_list_capabilities', | ||
| arguments: {}, | ||
| }); | ||
| expect(response.structuredContent).toEqual({ | ||
| project: { | ||
| analyze_runtime_environment: `Analyze a Node.js project in the specified root directory to determine compatibility with Serenity/JS. Detect available command line tools. Check for any runtime issues, explains their causes, and provides recommended fixes.`, | ||
| analyze_dependencies: `List the Node.js packages used by the project in the specified root directory to determine compatibility with Serenity/JS. Check for compatibility issues and recommend any missing packages that should be installed.`, | ||
| configure_playwright_test: 'Configure Playwright Test for use with Serenity/JS', | ||
| configure_package_json_scripts: 'Configure NPM scripts in package.json to include commands for running tests with Serenity/JS', | ||
| create_example_test_file: 'Create an example test file demonstrating writing Serenity/JS test scenarios', | ||
| run_test: 'Discover the commands to run Serenity/JS test scenarios', | ||
| }, | ||
| inspection: { | ||
| page_element_resolver: 'Define a selector identifying a page element based on its reference from the accessibility snapshot', | ||
| snapshot: 'Capture an accessibility snapshot of the website to detect the elements of interest', | ||
| }, | ||
| test_automation: { | ||
| assertions: { | ||
| activities: { | ||
| ensure: { | ||
| that: 'Ensure.that($actual, $expectation) - Verify if the resolved value of the provided question meets the specified expectation', | ||
| }, | ||
| }, | ||
| questions: { | ||
| equals: 'equals($expected) - Check if the actual value of type T equals the expected value of the same type T', | ||
| includes: 'includes($expected) - Check if the actual string value includes the expected substring', | ||
| }, | ||
| }, | ||
| web: { | ||
| activities: { | ||
| click: { | ||
| on: 'Click.on($pageElement) - Click on a page element', | ||
| }, | ||
| navigate: { | ||
| to: 'Navigate.to($url) - Navigate to a specific URL in the browser', | ||
| back: 'Navigate.back() - Navigate back in the browser history', | ||
| forward: 'Navigate.forward() - Navigate forward in the browser history', | ||
| reload_page: 'Navigate.reloadPage() - Reload the current page in the browser', | ||
| } | ||
| }, | ||
| questions: { | ||
| page: { | ||
| current: { | ||
| name: 'Page.current().name() - A question that retrieves the name of the current page in the browser', | ||
| title: 'Page.current().title() - A question that retrieves the title of the current page in the browser', | ||
| url: { | ||
| href: 'Page.current().url().href - A question that retrieves the URL of the current page in the browser.', | ||
| }, | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| }); | ||
| }); | ||
| }); |
46 changes: 46 additions & 0 deletionsintegration/mcp/spec/project_analyze_runtime.spec.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| import path from 'node:path'; | ||
| import { describe, expect, it } from '../src/mcp-api.js'; | ||
| const __dirname = path.dirname(new URL(import.meta.url).pathname); | ||
| describe('Project Analyze Runtime', () => { | ||
| it('instructs the user to install a test runner first if none is found', async ({ client }) => { | ||
| const rootDirectory = path.resolve(__dirname, '../examples/empty'); | ||
| const response = await client.callTool({ | ||
| name: 'serenity_project_analyze_runtime_environment', | ||
| arguments: { | ||
| rootDirectory, | ||
| }, | ||
| }); | ||
| expect(response.isError).not.toBe(true); | ||
| }); | ||
| it('analyzes the runtime of a node.js project to determine compatibility with Serenity/JS', async ({ client }) => { | ||
| const response = await client.callTool({ | ||
| name: 'serenity_project_analyze_runtime_environment', | ||
| arguments: { | ||
| rootDirectory: path.resolve(__dirname, '../examples/playwright-test'), | ||
| }, | ||
| }); | ||
| expect(response.isError).not.toBe(true); | ||
| // expect(response.structuredContent['missingDependencies']).toEqual([ | ||
| // `@serenity-js/assertions`, | ||
| // `@serenity-js/console-reporter`, | ||
| // `@serenity-js/core`, | ||
| // `@serenity-js/playwright`, | ||
| // `@serenity-js/playwright-test`, | ||
| // `@serenity-js/rest`, | ||
| // `@serenity-js/serenity-bdd`, | ||
| // `@serenity-js/web`, | ||
| // `npm-failsafe`, | ||
| // ]); | ||
| // expect(response.content[0].text).toEqual(` | ||
| // `); | ||
| }); | ||
| }); |
Oops, something went wrong.
Uh oh!
There was an error while loading.Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.