diff --git a/.github/workflows/integration_test_windows.yml b/.github/workflows/integration_test_windows.yml new file mode 100644 index 00000000..914a0024 --- /dev/null +++ b/.github/workflows/integration_test_windows.yml @@ -0,0 +1,27 @@ +name: Windows App Integration Test + +on: + pull_request: + branches: [main] + push: + branches: [main] + +jobs: + integration-windows-test: + runs-on: windows-latest + steps: + - name: Github checkout + uses: actions/checkout@v4 + - name: Build + uses: ./.github/actions/build/windows/app + with: + build-gpu: 'cpu' + sign-and-publish: false + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + - name: Run Playwright Tests + run: npm run test:e2e + - name: Upload screenshots + uses: actions/upload-artifact@v3 + with: + name: screenshot + path: screenshot*.png diff --git a/playwright.config.ts b/playwright.config.ts index 6d972f45..56d275bf 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -1,6 +1,7 @@ import { defineConfig } from '@playwright/test'; export default defineConfig({ - testMatch: 'src/__tests__/e2e/*.test.ts', - timeout: 1000000, + testDir: './tests/integration', + /* Run local instance before starting the tests */ + globalSetup: require.resolve('./playwright.setup'), }); diff --git a/playwright.setup.ts b/playwright.setup.ts new file mode 100644 index 00000000..0c74fcfa --- /dev/null +++ b/playwright.setup.ts @@ -0,0 +1,22 @@ +import { type FullConfig } from '@playwright/test'; +import { spawn } from 'child_process'; + +async function globalSetup(config: FullConfig) { + console.log('globalSetup'); + + return new Promise(async (resolve, reject) => { + const electron = spawn('node', ['./scripts/launchdev.js']); + + electron.on('close', () => { + reject('process failed to start'); + }); + + electron.stdout.on('data', (data) => { + if (data.indexOf('App ready') >= 0) { + resolve(); + } + }); + }); +} + +export default globalSetup; diff --git a/scripts/launchdev.js b/scripts/launchdev.js index 649d24a2..8850afbd 100644 --- a/scripts/launchdev.js +++ b/scripts/launchdev.js @@ -38,11 +38,14 @@ function setupMainPackageWatcher() { electronApp = null; } + const args = process.env.CI ? ['--remote-debugging-port=9000', '--remote-allow-origins=http://127.0.0.1:9000' ] : ['--inspect=9223'] + /** Spawn new electron process */ - electronApp = spawn(String(electronPath), ['--inspect=9223', '.'], { + electronApp = spawn(String(electronPath), [...args, '.'], { stdio: 'inherit', }); + electronApp.addListener('') /** Stops the watch script when the application has been quit */ electronApp.addListener('exit', process.exit); }, diff --git a/src/utils.ts b/src/utils.ts index 1fa6f7f5..69925a6d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -116,6 +116,10 @@ export async function validateHardware(): Promise { const graphics = await si.graphics(); const hasNvidia = graphics.controllers.some((controller) => controller.vendor.toLowerCase().includes('nvidia')); + if (process.env.CI) { + return { isValid: true }; // Temporary workaround for testing with Playwright + } + if (!hasNvidia) { try { // wmic is unreliable. Check in PS. diff --git a/tests/integration/startup.spec.ts b/tests/integration/startup.spec.ts new file mode 100644 index 00000000..9edbd1cd --- /dev/null +++ b/tests/integration/startup.spec.ts @@ -0,0 +1,50 @@ +import { test, expect } from '@playwright/test'; +import { chromium } from '@playwright/test'; + +test('has title', async () => { + const browser = await chromium.connectOverCDP('http://127.0.0.1:9000'); + + expect(browser.isConnected()).toBeTruthy(); + expect(browser.contexts().length).toBeGreaterThan(0); + + const context = browser.contexts()[0]; + const pages = context.pages(); + + expect(pages).toHaveLength(1); + const page = pages[0]; + + // Expect a title "to contain" a substring. + await expect(page).toHaveTitle(/ComfyUI/); + + const getStartedButton = page.getByText('Get Started'); + + await expect(getStartedButton).toBeVisible(); + await expect(getStartedButton).toBeEnabled(); + + await page.screenshot({ path: 'screenshot-load.png' }); + + await getStartedButton.click(); + + await expect(page.getByText('Choose Installation Location')).toBeVisible(); + + await page.screenshot({ path: 'screenshot-get-started.png' }); + + let nextButton = page.getByRole('button', { name: 'Next' }); + + await expect(nextButton).toBeVisible(); + await expect(nextButton).toBeEnabled(); + + await nextButton.click(); + + await expect(page.getByText('Migrate from Existing Installation')).toBeVisible(); + + await page.screenshot({ path: 'screenshot-migrate.png' }); + + nextButton = page.getByRole('button', { name: 'Next' }); + + await nextButton.click(); + + await expect(page.getByText('Desktop App Settings')).toBeVisible(); + + await page.screenshot({ path: 'screenshot-install.png' }); +});