@iblai/mcp 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +103 -97
- package/dist/index.js.map +1 -1
- package/dist/prompts/create-playwright-test.d.ts +2 -0
- package/dist/prompts/create-playwright-test.d.ts.map +1 -0
- package/dist/prompts/create-playwright-test.js +103 -0
- package/dist/prompts/create-playwright-test.js.map +1 -0
- package/dist/prompts/index.d.ts +4 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +4 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/setup-e2e-testing.d.ts +2 -0
- package/dist/prompts/setup-e2e-testing.d.ts.map +1 -0
- package/dist/prompts/setup-e2e-testing.js +162 -0
- package/dist/prompts/setup-e2e-testing.js.map +1 -0
- package/dist/prompts/setup-new-app.d.ts +2 -0
- package/dist/prompts/setup-new-app.d.ts.map +1 -0
- package/dist/prompts/setup-new-app.js +226 -0
- package/dist/prompts/setup-new-app.js.map +1 -0
- package/dist/resources/data-layer.js +14 -14
- package/dist/resources/guides-layout.js +5 -5
- package/dist/resources/guides-playwright.d.ts +8 -0
- package/dist/resources/guides-playwright.d.ts.map +1 -0
- package/dist/resources/guides-playwright.js +235 -0
- package/dist/resources/guides-playwright.js.map +1 -0
- package/dist/resources/guides-rbac.js +2 -2
- package/dist/resources/guides-theme.js +4 -4
- package/dist/resources/index.d.ts +3 -1
- package/dist/resources/index.d.ts.map +1 -1
- package/dist/resources/index.js +5 -1
- package/dist/resources/index.js.map +1 -1
- package/dist/resources/packages-overview.d.ts.map +1 -1
- package/dist/resources/packages-overview.js +12 -6
- package/dist/resources/packages-overview.js.map +1 -1
- package/dist/resources/packages-playwright.d.ts +8 -0
- package/dist/resources/packages-playwright.d.ts.map +1 -0
- package/dist/resources/packages-playwright.js +161 -0
- package/dist/resources/packages-playwright.js.map +1 -0
- package/dist/resources/web-containers.js +22 -22
- package/dist/resources/web-utils.js +9 -9
- package/dist/tools/api-query-info.d.ts.map +1 -1
- package/dist/tools/api-query-info.js +248 -238
- package/dist/tools/api-query-info.js.map +1 -1
- package/dist/tools/component-info.d.ts.map +1 -1
- package/dist/tools/component-info.js +650 -469
- package/dist/tools/component-info.js.map +1 -1
- package/dist/tools/hook-info.js +97 -97
- package/dist/tools/index.d.ts +15 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +3 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/page-template.js +8 -8
- package/dist/tools/page-template.js.map +1 -1
- package/dist/tools/playwright-helper-info.d.ts +16 -0
- package/dist/tools/playwright-helper-info.d.ts.map +1 -0
- package/dist/tools/playwright-helper-info.js +849 -0
- package/dist/tools/playwright-helper-info.js.map +1 -0
- package/dist/tools/provider-setup.js +4 -4
- package/dist/tools/provider-setup.js.map +1 -1
- package/package.json +19 -6
package/dist/index.js
CHANGED
|
@@ -1,123 +1,129 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
3
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
-
import {
|
|
4
|
+
import { z } from 'zod';
|
|
5
5
|
// Import resources
|
|
6
6
|
import { RESOURCES } from './resources/index.js';
|
|
7
7
|
// Import tools
|
|
8
|
-
import {
|
|
8
|
+
import { getComponentInfo, getHookInfo, getProviderSetup, getApiQueryInfo, createPageTemplate, getPlaywrightHelperInfo, } from './tools/index.js';
|
|
9
|
+
// Import prompts
|
|
10
|
+
import { generateE2ESetupPrompt, generateCreateTestPrompt, generateSetupNewAppPrompt, } from './prompts/index.js';
|
|
9
11
|
// ============================================================================
|
|
10
12
|
// IBL FRONTEND MCP SERVER
|
|
11
13
|
// ============================================================================
|
|
12
14
|
// This MCP server provides comprehensive documentation and guidance for
|
|
13
|
-
// working with the IBL frontend packages: web-containers, web-utils,
|
|
15
|
+
// working with the IBL frontend packages: web-containers, web-utils,
|
|
16
|
+
// data-layer, and @iblai/iblai-js/playwright
|
|
14
17
|
// ============================================================================
|
|
15
|
-
const server = new
|
|
18
|
+
const server = new McpServer({
|
|
16
19
|
name: 'ibl-frontend-mcp',
|
|
17
20
|
version: '1.0.0',
|
|
18
|
-
}, {
|
|
19
|
-
capabilities: {
|
|
20
|
-
resources: {},
|
|
21
|
-
tools: {},
|
|
22
|
-
},
|
|
23
21
|
});
|
|
24
22
|
// ============================================================================
|
|
25
|
-
//
|
|
23
|
+
// RESOURCES
|
|
26
24
|
// ============================================================================
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
resources: Object.entries(RESOURCES).map(([uri, resource]) => ({
|
|
30
|
-
uri,
|
|
31
|
-
name: resource.name,
|
|
32
|
-
description: resource.description,
|
|
33
|
-
mimeType: resource.mimeType,
|
|
34
|
-
})),
|
|
35
|
-
};
|
|
36
|
-
});
|
|
37
|
-
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
38
|
-
const uri = request.params.uri;
|
|
39
|
-
const resource = RESOURCES[uri];
|
|
40
|
-
if (!resource) {
|
|
41
|
-
throw new Error(`Resource not found: ${uri}`);
|
|
42
|
-
}
|
|
43
|
-
return {
|
|
25
|
+
for (const resource of Object.values(RESOURCES)) {
|
|
26
|
+
server.registerResource(resource.name, resource.uri, { description: resource.description, mimeType: resource.mimeType }, async (uri) => ({
|
|
44
27
|
contents: [
|
|
45
28
|
{
|
|
46
|
-
uri,
|
|
29
|
+
uri: uri.href,
|
|
47
30
|
mimeType: resource.mimeType,
|
|
48
31
|
text: resource.content,
|
|
49
32
|
},
|
|
50
33
|
],
|
|
51
|
-
};
|
|
52
|
-
}
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
53
36
|
// ============================================================================
|
|
54
|
-
//
|
|
37
|
+
// TOOLS
|
|
55
38
|
// ============================================================================
|
|
56
|
-
server.
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
39
|
+
server.registerTool('get_component_info', {
|
|
40
|
+
description: 'Get detailed information about a specific UI component from web-containers',
|
|
41
|
+
inputSchema: { componentName: z.string().describe('Name of the component (e.g., Button, Card, Dialog, Profile, NotificationDropdown)') },
|
|
42
|
+
}, async ({ componentName }) => ({
|
|
43
|
+
content: [{ type: 'text', text: getComponentInfo(componentName) }],
|
|
44
|
+
}));
|
|
45
|
+
server.registerTool('get_hook_info', {
|
|
46
|
+
description: 'Get detailed information about a custom React hook from web-utils or data-layer',
|
|
47
|
+
inputSchema: { hookName: z.string().describe('Name of the hook (e.g., useAdvancedChat, useMentorSettings)') },
|
|
48
|
+
}, async ({ hookName }) => ({
|
|
49
|
+
content: [{ type: 'text', text: getHookInfo(hookName) }],
|
|
50
|
+
}));
|
|
51
|
+
server.registerTool('get_provider_setup', {
|
|
52
|
+
description: 'Get provider setup code for an IBL app (AuthProvider, TenantProvider, etc.)',
|
|
53
|
+
inputSchema: {
|
|
54
|
+
appType: z.string().describe('Type of IBL app (e.g., mentor, skills, auth)'),
|
|
55
|
+
features: z.array(z.string()).optional().describe('Optional features to include (e.g., chat, analytics, rbac)'),
|
|
56
|
+
},
|
|
57
|
+
}, async ({ appType, features }) => ({
|
|
58
|
+
content: [{ type: 'text', text: getProviderSetup(appType, features || []) }],
|
|
59
|
+
}));
|
|
60
|
+
server.registerTool('get_api_query_info', {
|
|
61
|
+
description: 'Get detailed information about an RTK Query API hook from data-layer',
|
|
62
|
+
inputSchema: { queryName: z.string().describe('Name of the RTK Query API hook (e.g., useGetMentorSettingsQuery)') },
|
|
63
|
+
}, async ({ queryName }) => ({
|
|
64
|
+
content: [{ type: 'text', text: getApiQueryInfo(queryName) }],
|
|
65
|
+
}));
|
|
66
|
+
server.registerTool('create_page_template', {
|
|
67
|
+
description: 'Generate a Next.js page template with IBL providers and components',
|
|
68
|
+
inputSchema: {
|
|
69
|
+
pageName: z.string().describe('Name of the page to create (e.g., Dashboard, Settings)'),
|
|
70
|
+
appType: z.string().describe('Type of IBL app (e.g., mentor, skills, auth)'),
|
|
71
|
+
features: z.array(z.string()).optional().describe('Optional features to include'),
|
|
72
|
+
},
|
|
73
|
+
}, async ({ pageName, appType, features }) => ({
|
|
74
|
+
content: [{ type: 'text', text: createPageTemplate(pageName, appType, features || []) }],
|
|
75
|
+
}));
|
|
76
|
+
server.registerTool('get_playwright_helper_info', {
|
|
77
|
+
description: 'Get detailed documentation for a specific Playwright test helper from @iblai/iblai-js/playwright',
|
|
78
|
+
inputSchema: { helperName: z.string().describe('Name of the Playwright helper (e.g., createPlaywrightConfig, reliableClick, safeWaitForURL, createAuthSetup)') },
|
|
79
|
+
}, async ({ helperName }) => ({
|
|
80
|
+
content: [{ type: 'text', text: getPlaywrightHelperInfo(helperName) }],
|
|
81
|
+
}));
|
|
82
|
+
// ============================================================================
|
|
83
|
+
// PROMPTS
|
|
84
|
+
// ============================================================================
|
|
85
|
+
server.registerPrompt('setup-e2e-testing', {
|
|
86
|
+
description: 'Generate instructions for setting up Playwright E2E testing in an IBL app',
|
|
87
|
+
argsSchema: {
|
|
88
|
+
appType: z.enum(['mentor', 'skills', 'auth', 'custom']).describe('Type of IBL app to set up E2E testing for'),
|
|
89
|
+
appName: z.string().optional().describe('Optional custom app name (defaults to appType)'),
|
|
90
|
+
},
|
|
91
|
+
}, async ({ appType, appName }) => ({
|
|
92
|
+
messages: [
|
|
93
|
+
{
|
|
94
|
+
role: 'user',
|
|
95
|
+
content: { type: 'text', text: generateE2ESetupPrompt(appType, appName) },
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
}));
|
|
99
|
+
server.registerPrompt('create-playwright-test', {
|
|
100
|
+
description: 'Generate a Playwright E2E test for a specific feature using IBL SDK conventions',
|
|
101
|
+
argsSchema: {
|
|
102
|
+
feature: z.string().describe('Feature to write a test for (e.g., login, mentor creation, chat)'),
|
|
103
|
+
appType: z.enum(['mentor', 'skills', 'auth', 'custom']).describe('Type of IBL app'),
|
|
104
|
+
},
|
|
105
|
+
}, async ({ feature, appType }) => ({
|
|
106
|
+
messages: [
|
|
107
|
+
{
|
|
108
|
+
role: 'user',
|
|
109
|
+
content: { type: 'text', text: generateCreateTestPrompt(feature, appType) },
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
}));
|
|
113
|
+
server.registerPrompt('setup-new-app', {
|
|
114
|
+
description: 'Generate comprehensive setup instructions for a new IBL app with providers, store, and E2E testing',
|
|
115
|
+
argsSchema: {
|
|
116
|
+
appType: z.enum(['mentor', 'skills', 'auth', 'custom']).describe('Type of IBL app to set up'),
|
|
117
|
+
features: z.array(z.string()).optional().describe('Optional features: rbac, analytics, chat, e2e'),
|
|
118
|
+
},
|
|
119
|
+
}, async ({ appType, features }) => ({
|
|
120
|
+
messages: [
|
|
121
|
+
{
|
|
122
|
+
role: 'user',
|
|
123
|
+
content: { type: 'text', text: generateSetupNewAppPrompt(appType, features) },
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
}));
|
|
121
127
|
// ============================================================================
|
|
122
128
|
// SERVER STARTUP
|
|
123
129
|
// ============================================================================
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-playwright-test.d.ts","sourceRoot":"","sources":["../../src/prompts/create-playwright-test.ts"],"names":[],"mappings":"AAAA,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAuGjF"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
export function generateCreateTestPrompt(feature, appType) {
|
|
2
|
+
const hostVar = appType === 'mentor'
|
|
3
|
+
? 'MENTOR_NEXTJS_HOST'
|
|
4
|
+
: appType === 'skills'
|
|
5
|
+
? 'SKILLS_HOST'
|
|
6
|
+
: 'APP_HOST';
|
|
7
|
+
return `Write a Playwright E2E test for the "${feature}" feature in an IBL.ai ${appType} app.
|
|
8
|
+
|
|
9
|
+
## Conventions
|
|
10
|
+
|
|
11
|
+
### Imports
|
|
12
|
+
|
|
13
|
+
\`\`\`typescript
|
|
14
|
+
// Core Playwright (always import test/expect from here)
|
|
15
|
+
import { test, expect, Page } from '@playwright/test';
|
|
16
|
+
|
|
17
|
+
// SDK utilities (import helpers from here)
|
|
18
|
+
import {
|
|
19
|
+
logger,
|
|
20
|
+
safeWaitForURL,
|
|
21
|
+
waitForPageReady,
|
|
22
|
+
reliableClick,
|
|
23
|
+
reliableFill,
|
|
24
|
+
waitForDialogReady,
|
|
25
|
+
closeWithEsc,
|
|
26
|
+
expectNoAccessibilityViolations,
|
|
27
|
+
} from '@iblai/iblai-js/playwright';
|
|
28
|
+
|
|
29
|
+
// App-specific env vars
|
|
30
|
+
import { ${hostVar} } from '../utils';
|
|
31
|
+
\`\`\`
|
|
32
|
+
|
|
33
|
+
### Test Structure
|
|
34
|
+
|
|
35
|
+
\`\`\`typescript
|
|
36
|
+
test.describe('${feature}', () => {
|
|
37
|
+
test.beforeEach(async ({ page }) => {
|
|
38
|
+
await page.goto(${hostVar});
|
|
39
|
+
await waitForPageReady(page);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('should ...', async ({ page }) => {
|
|
43
|
+
// Use logger for debugging
|
|
44
|
+
logger.info('Starting test step');
|
|
45
|
+
|
|
46
|
+
// Use reliableClick for buttons (retries on detached/hidden elements)
|
|
47
|
+
await reliableClick(page, page.getByRole('button', { name: 'Action' }));
|
|
48
|
+
|
|
49
|
+
// Use reliableFill for inputs (clears, fills, verifies value)
|
|
50
|
+
await reliableFill(page, page.getByLabel('Name'), 'Test Value');
|
|
51
|
+
|
|
52
|
+
// Use safeWaitForURL for navigation (handles browser quirks)
|
|
53
|
+
await safeWaitForURL(page, (url) => url.pathname.includes('/target'));
|
|
54
|
+
|
|
55
|
+
// Standard Playwright assertions
|
|
56
|
+
await expect(page.getByText('Expected')).toBeVisible();
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
\`\`\`
|
|
60
|
+
|
|
61
|
+
### Available Helpers
|
|
62
|
+
|
|
63
|
+
**Navigation:**
|
|
64
|
+
- \`safeWaitForURL(page, urlMatcher, options?)\` — Browser-safe URL waiting
|
|
65
|
+
- \`waitForPageLoad(page)\` — Full page load (load + DOM + networkidle)
|
|
66
|
+
- \`isFirefox(page)\` — Check if Firefox (for browser-specific logic)
|
|
67
|
+
|
|
68
|
+
**Page Interaction:**
|
|
69
|
+
- \`waitForPageReady(page, timeout?)\` — Wait for document.readyState complete
|
|
70
|
+
- \`reliableClick(page, locator, timeout?, maxRetries?)\` — Click with retry
|
|
71
|
+
- \`reliableFill(page, locator, value, timeout?, maxRetries?)\` — Fill with retry
|
|
72
|
+
- \`waitForElementStable(page, locator, timeout?)\` — Wait for element stability
|
|
73
|
+
- \`waitForDialogReady(page, dialogLocator, timeout?)\` — Wait for dialog
|
|
74
|
+
- \`selectDateFromCalendar(page, dialogLocator, targetDate, timeout?)\` — Date picker
|
|
75
|
+
- \`closeWithEsc(page)\` — Press Escape to close modals
|
|
76
|
+
|
|
77
|
+
**Assertions:**
|
|
78
|
+
- \`expectNoAccessibilityViolations(page)\` — Full page axe-core audit
|
|
79
|
+
- \`expectNoAccessibilityViolationsOnDialogs(page, rules?, exclude?)\` — Dialog a11y
|
|
80
|
+
|
|
81
|
+
**Auth:**
|
|
82
|
+
- \`loginWithEmailAndPassword(page, username, password, hostUrl)\` — Login flow
|
|
83
|
+
- \`signUpWithEmailAndPassword(page, authHost, postSignUpUrl, credentials?)\` — Sign up
|
|
84
|
+
|
|
85
|
+
**Utilities:**
|
|
86
|
+
- \`logger\` — Winston logger (info locally, silent in CI)
|
|
87
|
+
- \`retry(action, errorMessage, retryCount?)\` — Generic retry
|
|
88
|
+
- \`checkAdminStatus(page)\` — Check admin from localStorage
|
|
89
|
+
|
|
90
|
+
### Best Practices
|
|
91
|
+
|
|
92
|
+
1. **Use \`safeWaitForURL\` instead of \`page.waitForURL\`** — handles Firefox NS_BINDING_ABORTED errors
|
|
93
|
+
2. **Use \`reliableClick\`/\`reliableFill\`** — handles detached elements and race conditions
|
|
94
|
+
3. **Use \`waitForPageReady\` after navigation** — ensures page is interactive
|
|
95
|
+
4. **Use \`logger.info()\` for debugging** — visible locally, suppressed in CI
|
|
96
|
+
5. **Use \`data-testid\` attributes** for element selection when role-based selectors are unreliable
|
|
97
|
+
6. **Set timeouts generously** — use \`test.setTimeout()\` for slow operations
|
|
98
|
+
7. **Use \`test.describe\` blocks** to group related tests
|
|
99
|
+
8. **Add accessibility tests** with \`expectNoAccessibilityViolations\`
|
|
100
|
+
|
|
101
|
+
Now write the test for "${feature}". Include appropriate beforeEach setup, multiple test cases covering happy path and edge cases, and use the SDK helpers where appropriate.`;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=create-playwright-test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-playwright-test.js","sourceRoot":"","sources":["../../src/prompts/create-playwright-test.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,wBAAwB,CAAC,OAAe,EAAE,OAAe;IACvE,MAAM,OAAO,GACX,OAAO,KAAK,QAAQ;QAClB,CAAC,CAAC,oBAAoB;QACtB,CAAC,CAAC,OAAO,KAAK,QAAQ;YACpB,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,UAAU,CAAC;IAEnB,OAAO,wCAAwC,OAAO,0BAA0B,OAAO;;;;;;;;;;;;;;;;;;;;;;;WAuB9E,OAAO;;;;;;iBAMD,OAAO;;sBAEF,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BA+DH,OAAO,6IAA6I,CAAC;AAC/K,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-e2e-testing.d.ts","sourceRoot":"","sources":["../../src/prompts/setup-e2e-testing.ts"],"names":[],"mappings":"AAAA,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAoKhF"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
export function generateE2ESetupPrompt(appType, appName) {
|
|
2
|
+
const name = appName || appType;
|
|
3
|
+
const hostVar = appType === 'mentor'
|
|
4
|
+
? 'MENTOR_NEXTJS_HOST'
|
|
5
|
+
: appType === 'skills'
|
|
6
|
+
? 'SKILLS_HOST'
|
|
7
|
+
: appType === 'auth'
|
|
8
|
+
? 'AUTH_HOST'
|
|
9
|
+
: 'APP_HOST';
|
|
10
|
+
const platformName = appType === 'mentor' ? 'mentornextjs' : appType === 'skills' ? 'skills' : name;
|
|
11
|
+
return `Set up Playwright E2E testing for an IBL.ai ${appType} app called "${name}" using @iblai/iblai-js/playwright.
|
|
12
|
+
|
|
13
|
+
## What to create
|
|
14
|
+
|
|
15
|
+
### 1. e2e/playwright.config.ts
|
|
16
|
+
|
|
17
|
+
\`\`\`typescript
|
|
18
|
+
import { createPlaywrightConfig } from '@iblai/iblai-js/playwright';
|
|
19
|
+
import dotenv from 'dotenv';
|
|
20
|
+
import path from 'path';
|
|
21
|
+
|
|
22
|
+
dotenv.config({ path: path.resolve(__dirname, '.env.development') });
|
|
23
|
+
|
|
24
|
+
export default createPlaywrightConfig({
|
|
25
|
+
platforms: [
|
|
26
|
+
{
|
|
27
|
+
name: '${platformName}',
|
|
28
|
+
dependencies: ['setup'],
|
|
29
|
+
otherTestMatch: ['**${platformName}/*/*.spec.ts'],
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
});
|
|
33
|
+
\`\`\`
|
|
34
|
+
|
|
35
|
+
This generates per-browser auth setup projects (setup-chrome, setup-firefox, setup-safari, setup-edge) and test projects for each platform/browser combination. CI mode: retries=3, workers=1, headless, trace=retain-on-failure.
|
|
36
|
+
|
|
37
|
+
### 2. e2e/auth.setup.ts
|
|
38
|
+
|
|
39
|
+
\`\`\`typescript
|
|
40
|
+
import { test as setup, createAuthSetup } from '@iblai/iblai-js/playwright';
|
|
41
|
+
|
|
42
|
+
setup(
|
|
43
|
+
'authenticate',
|
|
44
|
+
createAuthSetup({
|
|
45
|
+
hostUrl: process.env.${hostVar} || '',
|
|
46
|
+
authHost: process.env.AUTH_HOST || '',
|
|
47
|
+
appName: '${appType}',
|
|
48
|
+
postLoginUrlMatcher: (url) =>
|
|
49
|
+
url.href.includes('/platform/') || url.href.includes('/home'),
|
|
50
|
+
}),
|
|
51
|
+
);
|
|
52
|
+
\`\`\`
|
|
53
|
+
|
|
54
|
+
Authenticates once per browser and saves storage state to \`playwright/.auth/user-{browser}.json\`. Supports auth flows: username_password (default), magic_link, sso, direct_sso.
|
|
55
|
+
|
|
56
|
+
### 3. e2e/custom-reporter.ts
|
|
57
|
+
|
|
58
|
+
\`\`\`typescript
|
|
59
|
+
export { CustomReporter as default } from '@iblai/iblai-js/playwright';
|
|
60
|
+
\`\`\`
|
|
61
|
+
|
|
62
|
+
### 4. e2e/.env.development
|
|
63
|
+
|
|
64
|
+
\`\`\`
|
|
65
|
+
${hostVar}=https://${name}.example.com
|
|
66
|
+
AUTH_HOST=https://auth.example.com
|
|
67
|
+
PLAYWRIGHT_USERNAME=test@example.com
|
|
68
|
+
PLAYWRIGHT_PASSWORD=testpassword
|
|
69
|
+
AUTH_FLOW=username_password
|
|
70
|
+
AUTH_IDP=
|
|
71
|
+
\`\`\`
|
|
72
|
+
|
|
73
|
+
### 5. e2e/tests/utils.ts
|
|
74
|
+
|
|
75
|
+
\`\`\`typescript
|
|
76
|
+
export const ${hostVar} = process.env.${hostVar} || '';
|
|
77
|
+
export const AUTH_HOST = process.env.AUTH_HOST || '';
|
|
78
|
+
\`\`\`
|
|
79
|
+
|
|
80
|
+
### 6. e2e/tests/helpers.ts
|
|
81
|
+
|
|
82
|
+
\`\`\`typescript
|
|
83
|
+
import { loginWithEmailAndPassword, logger } from '@iblai/iblai-js/playwright';
|
|
84
|
+
import { ${hostVar}, AUTH_HOST } from './utils';
|
|
85
|
+
|
|
86
|
+
export async function loginAsTestUser(page: import('@playwright/test').Page) {
|
|
87
|
+
const username = process.env.PLAYWRIGHT_USERNAME || '';
|
|
88
|
+
const password = process.env.PLAYWRIGHT_PASSWORD || '';
|
|
89
|
+
await loginWithEmailAndPassword(page, username, password, ${hostVar});
|
|
90
|
+
}
|
|
91
|
+
\`\`\`
|
|
92
|
+
|
|
93
|
+
### 7. Sample test file: e2e/tests/${platformName}/example.spec.ts
|
|
94
|
+
|
|
95
|
+
\`\`\`typescript
|
|
96
|
+
import { test, expect } from '@playwright/test';
|
|
97
|
+
import { logger, safeWaitForURL, waitForPageReady, reliableClick } from '@iblai/iblai-js/playwright';
|
|
98
|
+
import { ${hostVar} } from '../utils';
|
|
99
|
+
|
|
100
|
+
test.describe('Example Feature', () => {
|
|
101
|
+
test.beforeEach(async ({ page }) => {
|
|
102
|
+
await page.goto(${hostVar});
|
|
103
|
+
await waitForPageReady(page);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test('should load the page', async ({ page }) => {
|
|
107
|
+
logger.info('Checking page loaded');
|
|
108
|
+
await expect(page.getByRole('heading')).toBeVisible();
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test('should navigate on click', async ({ page }) => {
|
|
112
|
+
await reliableClick(page, page.getByRole('button', { name: 'Continue' }));
|
|
113
|
+
await safeWaitForURL(page, (url) => url.pathname.includes('/next'));
|
|
114
|
+
await expect(page.getByText('Next Page')).toBeVisible();
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
\`\`\`
|
|
118
|
+
|
|
119
|
+
### 8. Directory structure
|
|
120
|
+
|
|
121
|
+
\`\`\`
|
|
122
|
+
e2e/
|
|
123
|
+
├── playwright.config.ts
|
|
124
|
+
├── auth.setup.ts
|
|
125
|
+
├── custom-reporter.ts
|
|
126
|
+
├── .env.development
|
|
127
|
+
├── tests/
|
|
128
|
+
│ ├── utils.ts
|
|
129
|
+
│ ├── helpers.ts
|
|
130
|
+
│ └── ${platformName}/
|
|
131
|
+
│ └── example.spec.ts
|
|
132
|
+
└── playwright/
|
|
133
|
+
└── .auth/ # Created automatically by auth setup
|
|
134
|
+
\`\`\`
|
|
135
|
+
|
|
136
|
+
### 9. package.json scripts
|
|
137
|
+
|
|
138
|
+
\`\`\`json
|
|
139
|
+
{
|
|
140
|
+
"test:e2e": "playwright test --config e2e/playwright.config.ts",
|
|
141
|
+
"test:e2e:ui": "playwright test --config e2e/playwright.config.ts --ui",
|
|
142
|
+
"test:e2e:headed": "cross-env HEADED=true playwright test --config e2e/playwright.config.ts"
|
|
143
|
+
}
|
|
144
|
+
\`\`\`
|
|
145
|
+
|
|
146
|
+
### 10. Dependencies to install
|
|
147
|
+
|
|
148
|
+
\`\`\`bash
|
|
149
|
+
pnpm add -D @playwright/test @axe-core/playwright dotenv cross-env
|
|
150
|
+
npx playwright install
|
|
151
|
+
\`\`\`
|
|
152
|
+
|
|
153
|
+
## Key patterns
|
|
154
|
+
|
|
155
|
+
- Import \`test\` and \`expect\` from \`@playwright/test\` directly
|
|
156
|
+
- Import utilities (\`logger\`, \`safeWaitForURL\`, \`waitForPageReady\`, \`reliableClick\`, \`reliableFill\`) from \`@iblai/iblai-js/playwright\`
|
|
157
|
+
- Use \`safeWaitForURL\` instead of \`page.waitForURL\` — it handles Firefox NS_BINDING_ABORTED and Safari navigation policy errors
|
|
158
|
+
- Use \`reliableClick\`/\`reliableFill\` for flaky UI interactions
|
|
159
|
+
- Use \`waitForPageReady\` after navigation before assertions
|
|
160
|
+
- Use \`expectNoAccessibilityViolations(page)\` for a11y testing`;
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=setup-e2e-testing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-e2e-testing.js","sourceRoot":"","sources":["../../src/prompts/setup-e2e-testing.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,sBAAsB,CAAC,OAAe,EAAE,OAAgB;IACtE,MAAM,IAAI,GAAG,OAAO,IAAI,OAAO,CAAC;IAChC,MAAM,OAAO,GACX,OAAO,KAAK,QAAQ;QAClB,CAAC,CAAC,oBAAoB;QACtB,CAAC,CAAC,OAAO,KAAK,QAAQ;YACpB,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,OAAO,KAAK,MAAM;gBAClB,CAAC,CAAC,WAAW;gBACb,CAAC,CAAC,UAAU,CAAC;IAErB,MAAM,YAAY,GAChB,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;IAEjF,OAAO,+CAA+C,OAAO,gBAAgB,IAAI;;;;;;;;;;;;;;;;eAgBpE,YAAY;;4BAEC,YAAY;;;;;;;;;;;;;;;;2BAgBb,OAAO;;gBAElB,OAAO;;;;;;;;;;;;;;;;;;EAkBrB,OAAO,YAAY,IAAI;;;;;;;;;;;eAWV,OAAO,kBAAkB,OAAO;;;;;;;;WAQpC,OAAO;;;;;8DAK4C,OAAO;;;;qCAIhC,YAAY;;;;;WAKtC,OAAO;;;;sBAII,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA4BnB,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iEA8B2C,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-new-app.d.ts","sourceRoot":"","sources":["../../src/prompts/setup-new-app.ts"],"names":[],"mappings":"AAAA,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAM,EAAO,GACtB,MAAM,CAwOR"}
|