بنقرة واحدة
setup-e2e
Set up end-to-end testing framework with CI integration
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Set up end-to-end testing framework with CI integration
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
End-to-end orchestrated execution. Takes a feature description and drives the entire pipeline — plan, plan review (3 fresh reviewers), WU decomposition, 4-phase execution loop per WU, final review, COMMIT-READY emit. Honors user's git policy (no auto-commit).
`--default-domain` comes from the project-detect framework signal (orchestrator Step 5b / project-context); it only decides how UI files with no strong path marker are classified. `--risk-tier` is the WU's `risk_tier` fi
**Capture the WU baseline ONCE per WU, before attempt 1 (NOT on retries).** This is what makes file-scope checks correct across a multi-WU run where the user has not yet committed prior WUs (per the `ben yapacagim` git p
This gate has **two interchangeable execution paths that MUST emit the identical aggregated verdict object** (Step 3). The prose path below is the canonical fallback and the single source of truth for reviewer prompts an
A baton-based system for building mobile features across multiple Claude Code sessions with persistent progress tracking and simulator verification between steps.
Scaffold a Supabase/Playwright E2E harness for a Refine/TanStack web app using Telar's Arrange/Act patterns
| name | setup-e2e |
| description | Set up end-to-end testing framework with CI integration |
| source_type | command |
| source_file | commands/setup-e2e.md |
Migrated from commands/setup-e2e.md.
references/... or workflow/..., are packaged beside this SKILL.md.agents/..., commands/..., scripts/..., resources/..., rules/..., hooks/..., or templates/..., are packaged at this plugin root.skills/orchestration/...) is packaged under source/skills/orchestration/... for exact-reference lookups; all other Telar skills exist here only as the generated adapters under the plugin-root skills/ directory.../.. when reading support files or running packaged scripts./tl-telar:setup-e2e; invoke it as $setup-e2e or through @tl-telar.skills/orchestration/<name>, load the generated Codex skill at ../orchestration-<name>/SKILL.md first. The original source copy also exists under ../../source/skills/orchestration/<name>/SKILL.md for exact Telar-source references.Set up end-to-end testing for mobile apps.
Before selecting among mobile frameworks, check whether the target is a web app rather than a mobile app: inspect package.json deps (vite, @refinedev/*, @tanstack/react-router, astro) or the app path for a web project structure. If the target is a web app (Vite / Refine / TanStack Router / Astro), delegate directly to /tl-telar:setup-web-e2e instead of proceeding with the mobile framework selection below — that command owns the Playwright-based web E2E setup (supabase-e2e-harness, web-e2e-locators, web-e2e-catalog, web-e2e-review skills, web-e2e-testing-expert agent). Stop this command's flow once delegation happens.
agents:
- mobile-e2e-testing-expert
| Framework | RN Support | Flutter | Learning Curve | CI Support |
|-----------|------------|---------|----------------|------------|
| Detox | Excellent | No | Medium | Good |
| Maestro | Good | Good | Low | Good |
| Appium | Good | Good | High | Excellent |
| Patrol | No | Excellent | Medium | Good |
# Install
yarn add -D detox jest-circus
# Initialize
npx detox init
// .detoxrc.js
module.exports = {
testRunner: {
args: {
config: 'e2e/jest.config.js',
},
jest: {
setupTimeout: 120000,
},
},
apps: {
'ios.release': {
type: 'ios.app',
binaryPath: 'ios/build/MyApp.app',
build: 'xcodebuild -workspace ios/MyApp.xcworkspace -scheme MyApp -configuration Release -sdk iphonesimulator -derivedDataPath ios/build',
},
'android.release': {
type: 'android.apk',
binaryPath: 'android/app/build/outputs/apk/release/app-release.apk',
build: 'cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release',
},
},
devices: {
simulator: {
type: 'ios.simulator',
device: { type: 'iPhone 15' },
},
emulator: {
type: 'android.emulator',
device: { avdName: 'Pixel_6_API_34' },
},
},
configurations: {
'ios.release': {
device: 'simulator',
app: 'ios.release',
},
'android.release': {
device: 'emulator',
app: 'android.release',
},
},
}
# Install Maestro
curl -Ls "https://get.maestro.mobile.dev" | bash
# Initialize
mkdir -p .maestro
# .maestro/config.yaml
appId: com.myapp
# pubspec.yaml
dev_dependencies:
integration_test:
sdk: flutter
flutter_test:
sdk: flutter
skills:
- mock-strategies
e2e/
├── flows/
│ ├── auth.test.ts
│ ├── onboarding.test.ts
│ └── purchase.test.ts
├── helpers/
│ ├── auth.ts
│ └── navigation.ts
├── jest.config.js
└── setup.ts
// e2e/flows/auth.test.ts
describe('Authentication', () => {
beforeAll(async () => {
await device.launchApp({ newInstance: true })
})
beforeEach(async () => {
await device.reloadReactNative()
})
it('should show login screen', async () => {
await expect(element(by.id('login-screen'))).toBeVisible()
})
it('should login with valid credentials', async () => {
await element(by.id('email-input')).typeText('test@example.com')
await element(by.id('password-input')).typeText('password123')
await element(by.id('login-button')).tap()
await waitFor(element(by.id('home-screen')))
.toBeVisible()
.withTimeout(5000)
})
it('should show error for invalid credentials', async () => {
await element(by.id('email-input')).typeText('wrong@example.com')
await element(by.id('password-input')).typeText('wrongpass')
await element(by.id('login-button')).tap()
await expect(element(by.text('Invalid credentials'))).toBeVisible()
})
})
# .maestro/flows/auth.yaml
appId: com.myapp
---
- launchApp:
clearState: true
- assertVisible: "Login"
- tapOn:
id: "email-input"
- inputText: "test@example.com"
- tapOn:
id: "password-input"
- inputText: "password123"
- tapOn: "Login"
- assertVisible: "Welcome"
// e2e/helpers/auth.ts
export async function login(email: string, password: string) {
await element(by.id('email-input')).typeText(email)
await element(by.id('password-input')).typeText(password)
await element(by.id('login-button')).tap()
}
export async function logout() {
await element(by.id('settings-tab')).tap()
await element(by.id('logout-button')).tap()
}
skills:
- ci-testing-integration
name: E2E Tests
on: [push, pull_request]
jobs:
e2e-ios:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Install pods
run: cd ios && pod install
- name: Build for testing
run: npx detox build --configuration ios.release
- name: Run E2E tests
run: npx detox test --configuration ios.release --headless
e2e-android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Start emulator
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 34
script: |
yarn install --frozen-lockfile
npx detox build --configuration android.release
npx detox test --configuration android.release
name: Maestro E2E
on: [push]
jobs:
test:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: mobile-dev-inc/action-maestro-cloud@v1
with:
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
app-file: app.apk