Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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 intomain
base:main
Choose a base branch
Loading
fromfeatures/mcp
Open
Show file tree
Hide file tree
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-molakJul 11, 2025
3c0877f
chore(mcp): corrected build script
jan-molakJul 11, 2025
594f077
chore(deps): updated pnpm
jan-molakJul 11, 2025
31c88eb
chore(deps): corrected cc script
jan-molakJul 11, 2025
1036c41
feat(mcp): support for Navigate interactions
jan-molakJul 11, 2025
09b836a
fix(mcp): corrected the shutdown hook
jan-molakJul 11, 2025
5b8ec87
fix(mcp): corrected the input schema definition
jan-molakJul 11, 2025
7e4a641
Merge branch 'main' into features/mcp
jan-molakJul 13, 2025
3e424ee
chore(mcp): version bump
jan-molakJul 13, 2025
fca2cda
chore(deps): updated playwright
jan-molakJul 13, 2025
d26083c
Merge branch 'main' into features/mcp
jan-molakJul 29, 2025
f63ebef
Merge branch 'main' into features/mcp
jan-molakAug 1, 2025
6fea805
feat(core): internal ModuleLoader supports importing ESM modules
jan-molakAug 15, 2025
1ad6675
feat(mcp): new MCP server architecture
jan-molakAug 20, 2025
289c3c1
fix(core): corrected module loader behaviour for CJS modules
jan-molakAug 20, 2025
d65a272
test(mcp): corrected configuration
jan-molakAug 20, 2025
a330ed6
Merge branch 'main' into features/mcp
jan-molakAug 20, 2025
e06a946
Merge branch 'main' into features/mcp
jan-molakAug 20, 2025
6ae5009
chore(mcp): version bump
jan-molakAug 20, 2025
d7308fb
chore(deps): updated playwright
jan-molakAug 21, 2025
6ebeb83
chore(deps): updated playwright
jan-molakAug 21, 2025
f011176
feat(mcp): moved test automation capabilities to a dedicated section …
jan-molakAug 21, 2025
7e3098e
test(mcp): cleaned up the test directory structure
jan-molakAug 21, 2025
807392c
fix(mcp): clarified the purpose of the descriptor
jan-molakAug 21, 2025
b238656
refactor(mcp): refactored the ListCapabilitiesController
jan-molakAug 23, 2025
4a91abc
refactor(mcp): improved naming in the output schema of the ListCapabi…
jan-molakAug 23, 2025
176e2bf
fix(mcp): first draft of project-related MCP capabilities
jan-molakAug 29, 2025
f0e77a1
Merge branch 'main' into features/mcp
jan-molakAug 31, 2025
4d77310
feat(mcp): support for configuring Playwright Test to use Serenity/JS
jan-molakSep 2, 2025
28ff81c
feat(mcp): capability to suggest package.json scripts for running Ser…
jan-molakSep 2, 2025
78e6550
feat(mcp): capability to generate an example test file
jan-molakSep 3, 2025
89b2732
fix(mcp): corrected typos in the template
jan-molakSep 6, 2025
ca36c0a
test(mcp): cleaned up the directory structure
jan-molakSep 6, 2025
6cdf812
fix(mcp): finished the prototype
jan-molakSep 7, 2025
a30c855
Merge branch 'main' into features/mcp
jan-molakSep 7, 2025
078ddb8
chore(deps): bumped version
jan-molakSep 7, 2025
c60c467
test(mcp): updated tests
jan-molakSep 7, 2025
b6112fe
fix(mcp): detect env variables
jan-molakSep 8, 2025
fcc114e
refactor(mcp): improved description
jan-molakSep 8, 2025
1530e1f
fix(mcp): added instructions on running tests
jan-molakSep 8, 2025
b12b138
fix(mcp): optimised the instructions
jan-molakSep 8, 2025
1d54486
fix(mcp): optimised the response from environment detector
jan-molakSep 9, 2025
50dcc05
refactor(mcp): cleaned up env vars section
jan-molakSep 9, 2025
b0d03dc
refactor(mcp): new MCP framework
jan-molakSep 13, 2025
3078d73
refactor(mcp): refactored the package structure
jan-molakSep 15, 2025
63d736c
refactor(mcp): implemented a replacement MCP server
jan-molakSep 17, 2025
03355d9
test(mcp): refactored the examples structure
jan-molakSep 17, 2025
9161e64
refactor(mcp): made actors an integral part of the MCP server
jan-molakSep 18, 2025
fce6e44
refactor(mcp): migrated the project_analyze_tool to the new pattern
jan-molakSep 20, 2025
d889c34
feat(mcp): finished the project analyzer tool
jan-molakSep 21, 2025
8445409
feat(mcp): implemented the install_dependencies tool
jan-molakSep 28, 2025
2af4222
Merge branch 'main' into features/mcp
jan-molakSep 28, 2025
a4ed425
feat(mcp): project analyze tool now detects the test runner
jan-molakSep 29, 2025
4297cf8
refactor(mcp): complain if no test runner is found when analysing the…
jan-molakSep 29, 2025
f66e7ad
fix(mcp): improved error handling in scenarios where test runner is n…
jan-molakSep 30, 2025
6ba4b77
feat(mcp): dependency installation and package.json configuration tools
jan-molakOct 4, 2025
18966c4
style(mcp): code clean-up
jan-molakOct 6, 2025
9bcbe16
Merge branch 'main' into features/mcp
jan-molakOct 6, 2025
2dd3ddd
Merge branch 'main' into features/mcp
jan-molakOct 6, 2025
6415a6c
chore(mcp): version bump
jan-molakOct 6, 2025
a99fc82
Merge branch 'main' into features/mcp
jan-molakOct 9, 2025
d2df8c9
feat(mcp): configure test runner tool
jan-molakOct 30, 2025
5dfe6e0
Merge branch 'main' into features/mcp
jan-molakNov 1, 2025
a5fd90c
Merge branch 'main' into features/mcp
jan-molakNov 7, 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
1 change: 1 addition & 0 deletions.github/workflows/main.yaml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -147,6 +147,7 @@ jobs:
strategy:
matrix:
module:
- mcp
- playwright-test
- playwright-test-ct
- playwright-web
Expand Down
15 changes: 0 additions & 15 deletionsexamples/webdriverio-cucumber/todo.md
View file
Open in desktop

This file was deleted.

8 changes: 4 additions & 4 deletionsintegration/jasmine/spec/screenplay.spec.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -51,7 +51,7 @@ describe('@serenity-js/Jasmine', function () {
}));

it('fails when discarding an ability results in Error', () =>
jasmine('examples/screenplay/ability-discard-error.spec.js')
jasmine('examples/screenplay/ability-close-error.spec.js')
.then(ifExitCodeIsOtherThan(3, logOutput))
.then(result => {
expect(result.exitCode).to.equal(3);
Expand All@@ -77,7 +77,7 @@ describe('@serenity-js/Jasmine', function () {
}));

it(`fails when discarding an ability doesn't complete within a timeout`, () =>
jasmine('examples/screenplay/ability-discard-timeout.spec.js')
jasmine('examples/screenplay/ability-close-timeout.spec.js')
.then(ifExitCodeIsOtherThan(3, logOutput))
.then(result => {
expect(result.exitCode).to.equal(3);
Expand All@@ -103,7 +103,7 @@ describe('@serenity-js/Jasmine', function () {
}));

it(`executes all the scenarios in the test suite even when some of them fail because of an error when discarding an ability`, () =>
jasmine('examples/screenplay/ability-discard-error-should-not-affect-stage-cue.spec.js')
jasmine('examples/screenplay/ability-close-error-should-not-affect-stage-cue.spec.js')
.then(ifExitCodeIsOtherThan(3, logOutput))
.then(result => {
expect(result.exitCode).to.equal(3);
Expand All@@ -125,7 +125,7 @@ describe('@serenity-js/Jasmine', function () {
.next(SceneFinished, event => {
expect(event.outcome).to.be.instanceOf(ExecutionSuccessful);
})
.next(SceneStarts, event => expect(event.details.name).to.equal(new Name('A screenplay scenario fails if the ability fails todiscard again')))
.next(SceneStarts, event => expect(event.details.name).to.equal(new Name('A screenplay scenario fails if the ability fails toclose again')))
.next(SceneFinished, event => {
const outcome: ProblemIndication = event.outcome as ProblemIndication;

Expand Down
9 changes: 9 additions & 0 deletionsintegration/mcp/.gitignore
View file
Open in desktop
Original file line numberDiff line numberDiff 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
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
{
"name": "@integration/mcp-examples-empty",
"private": true,
"config": {
"access": "private"
}
}
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
{
"name": "example-package-json-empty-scripts",
"version": "1.0.0",
"main": "index.js",
"scripts": {},
"description": ""
}
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
{
"name": "example-package-json-no-scripts",
"version": "1.0.0",
"main": "index.js",
"description": ""
}
View file
Open in desktop
Original file line numberDiff line numberDiff 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
View file
Open in desktop
Original file line numberDiff line numberDiff 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
View file
Open in desktop
Original file line numberDiff line numberDiff 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
View file
Open in desktop
Original file line numberDiff line numberDiff 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
View file
Open in desktop
Original file line numberDiff line numberDiff 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
View file
Open in desktop
Original file line numberDiff line numberDiff 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
View file
Open in desktop
Original file line numberDiff line numberDiff 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(`
// `);
});
});
Loading

[8]ページ先頭

©2009-2025 Movatter.jp