micro-integrator icon indicating copy to clipboard operation
micro-integrator copied to clipboard

Automated Test Cases for MI Copilot

Open kalaiyarasiganeshalingam opened this issue 11 months ago • 0 comments

Description

We can use the following code to sign in to MI Copilot. After signing in, a system-level pop-up appears before opening MI. This pop-up is controlled by the browser or operating system, not the web page. Because of that, Playwright cannot detect, intercept, or click it.

Image

Coding

import { Page, chromium } from "@playwright/test";
import { MACHINE_VIEW } from '@wso2-enterprise/mi-core';
import { page } from '../Utils';
import { ProjectExplorer } from "./ProjectExplorer";
import { Overview } from "./Overview";
import { exec } from 'child_process';
import util from 'util';
const execPromise = util.promisify(exec);

export class Copilot {

    constructor(private _page: Page) {}

    public async init() {
        let iframeTitle: string | null;
        try {
            const webview = await page.getCurrentWebview();
            iframeTitle = webview.title;
        } catch (error) {
            console.error("Error retrieving iframe title:", error);
            iframeTitle = null;
        }

        if (iframeTitle !== MACHINE_VIEW.ADD_ARTIFACT) {
            const projectExplorer = new ProjectExplorer(this._page);
            await projectExplorer.goToOverview("testProject");

            const overviewPage = new Overview(this._page);
            await overviewPage.init();
            await overviewPage.goToAddArtifact();    
        }

        await page.page.getByLabel('Open AI Panel').click();
    }

    public async signIn() {
        // Step 1: Click "Sign In" in iframe
        await page.page.waitForTimeout(5000);
        for (const frame of page.page.frames()) {
            const content = await frame.content();
            if (content.includes('MI Copilot Account Not Found')) {
            await frame.getByRole('button', { name: 'Sign In' }).click();
            break;
            }
        }
        
        // Step 2: Copy the auth URL
        await page.page.context().grantPermissions(['clipboard-read']);
        const copyButton = page.page.getByRole('button', { name: 'Copy' });
        await copyButton.click();
        await page.page.waitForTimeout(500);
        const authUrl = await page.page.evaluate(() => navigator.clipboard.readText());
        
        if (!authUrl.startsWith('http')) throw new Error('Invalid auth URL');
        
        // Step 3: Launch browser and log in
        const browser = await chromium.launch({ headless: false });
        const context = await browser.newContext();
        const loginPage = await context.newPage();
        await loginPage.goto(authUrl);
        
        await loginPage.getByPlaceholder('Username').fill('[email protected]');
        await loginPage.getByPlaceholder('Password').fill('Kalai@');
        await loginPage.getByTestId('login-page-continue-login-button').click();
        
        // Step 4: Wait for success screen
        await loginPage.waitForSelector('text=Authorization was successful', { timeout: 10000 });
        // Wait for popup container (maybe a div or shadow-root panel)
        const redirectedUrl = new URL(loginPage.url());
        console.log(redirectedUrl);
        const code = redirectedUrl.searchParams.get('code');
        const session_state = redirectedUrl.searchParams.get('session_state');
        const state = redirectedUrl.searchParams.get('state');
        
        if (!code || !state || !session_state ) throw new Error('Failed to extract code/state');
        const fullVSCodeUrl = `vscode://wso2.micro-integrator/signin?code=${encodeURIComponent(code)}&session_state=${encodeURIComponent(session_state)}&state=${encodeURIComponent(state)}`;
        await simulateVSCodeLaunch(fullVSCodeUrl);
    }
} 

async function simulateVSCodeLaunch(url: string): Promise<void> {
    try {
      console.log(`Simulating: code --open-url "${url}"`);
      const { stdout, stderr } = await execPromise(`code --open-url "${url}"`);
      if (stdout) console.log('VSCode Output:\n', stdout);
      if (stderr) console.warn('VSCode Warnings:\n', stderr);
    } catch (error) {
      console.error('Failed to launch VSCode:', error);
    }
}

Version

No response