Skip to content

Commit

Permalink
Merge pull request #6 from sshveta/initial_framework_commit
Browse files Browse the repository at this point in the history
[RFR] Initial framework commit for playwright tests
  • Loading branch information
sshveta authored Oct 16, 2024
2 parents cf40678 + 607abd7 commit 9255d4a
Show file tree
Hide file tree
Showing 9 changed files with 354 additions and 1 deletion.
11 changes: 11 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
####################
### EXAMPLE FILE ###
####################

# Do NOT edit this file unless adding new env variables
# Instead, copy it, remove the .example extension and provide your custom values
# For git password please use your generated git token, not a clear text password


VSCODE_EXECUTABLE_PATH='/usr/share/code/code'
VSIX_FILE_PATH='kai-vscode-plugin-0.0.3.vsix'
11 changes: 11 additions & 0 deletions .github/workflows/prettier.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: Code formatting
on: pull_request

jobs:
build:
name: Prettier
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- run: npm install .
- run: npm run check
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"singleQuote": true,
"semi": true,
"trailingComma": "es5",
"tabWidth": 2
}
70 changes: 69 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,69 @@
# kai-ci
# VSCode Automation with Playwright

This repository contains automated tests using Playwright to launch Visual Studio Code (VSCode) and install a specified extension from a VSIX file.

## Table of Contents

- [Features](#features)
- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Usage](#usage)
- [Test Structure](#test-structure)
- [Running Tests](#running-tests)
- [Contributing](#contributing)
- [License](#license)

## Features

Launch Visual Studio Code as an Electron application.
Install extensions from VSIX files.
Basic test structure using Playwright's Page Object Model.

## Prerequisites

Before you begin, ensure you have the following:

Node.js (version 14 or later) installed.
Playwright installed. You can install it using npm.
Visual Studio Code installed on your system.

## Installation

1. **Clone the Repository**

`git clone https://github.com/konveyor/kai-ci`
`cd kai-ci`

2. **Install Dependencies**

Install the required packages using npm:

`npm install`


## Usage

Create .env file and copy the content of .env.example into it and provide appropriate values:

VSCODE_EXECUTABLE_PATH='/usr/share/code/code'
VSIX_FILE_PATH='/home/sshveta/Downloads/kai-vscode-plugin-0.0.3.vsix'

## Running Tests

To run the automated tests, use the following command:

`npx playwright test`

This command will execute all tests in your repository. To run a specific test file:

`npx playwright test vscode.test.ts`

#### Code formatting using Prettier tool

1. Format code

`npm run format`

2. Check formatting

`npm run check`
93 changes: 93 additions & 0 deletions e2e/pages/vscode.pages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { _electron as electron, ElectronApplication, Page } from 'playwright';
import { execSync } from 'child_process';
import * as fs from 'fs';

class LaunchVSCodePage {
private vscodeApp?: ElectronApplication;
private window?: Page;

private constructor(vscodeApp: ElectronApplication, window: Page) {
this.vscodeApp = vscodeApp;
this.window = window;
}

public static async launchVSCode(
executablePath: string
): Promise<LaunchVSCodePage> {
try {
const vsixFilePath = process.env.VSIX_FILE_PATH;
if (vsixFilePath) {
console.log(`Installing extension from VSIX file: ${vsixFilePath}`);
await LaunchVSCodePage.installExtensionFromVSIX(vsixFilePath);
} else {
console.warn(
'VSIX_FILE_PATH environment variable is not set. Skipping extension installation.'
);
}

// Launch VSCode as an Electron app
const vscodeApp = await electron.launch({
executablePath: executablePath,
});

// Get the main window
const window = await vscodeApp.firstWindow();

// Return an instance of LaunchVSCodePage
return new LaunchVSCodePage(vscodeApp, window);
} catch (error) {
console.error('Error launching VSCode:', error);
throw error;
}
}

/**
* Installs an extension from a VSIX file using the VSCode CLI.
* This method is static because it is independent of the instance.
*/
private static async installExtensionFromVSIX(
vsixFilePath: string
): Promise<void> {
if (!fs.existsSync(vsixFilePath)) {
throw new Error(`VSIX file not found at path: ${vsixFilePath}`);
}

try {
// Execute command to install VSIX file using VSCode CLI
console.log(`Installing extension from ${vsixFilePath}...`);
execSync(`code --install-extension ${vsixFilePath}`, {
stdio: 'inherit',
});
console.log('Extension installed successfully.');
} catch (error) {
console.error('Error installing the VSIX extension:', error);
throw error;
}
}

/**
* Closes the VSCode instance.
*/
public async closeVSCode(): Promise<void> {
try {
if (this.vscodeApp) {
await this.vscodeApp.close();
console.log('VSCode closed successfully.');
}
} catch (error) {
console.error('Error closing VSCode:', error);
}
}

/**
* Returns the main window for further interactions.
*/
public getWindow(): Page {
if (!this.window) {
throw new Error('VSCode window is not initialized.');
}
return this.window;
}
}

export { LaunchVSCodePage };
34 changes: 34 additions & 0 deletions e2e/tests/vscode.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { test, expect } from '@playwright/test';
import { LaunchVSCodePage } from '../pages/vscode.pages';

test.describe('VSCode Tests', () => {
let vscodeApp: LaunchVSCodePage;

test.beforeAll(async () => {
const executablePath =
process.env.VSCODE_EXECUTABLE_PATH || '/usr/share/code/code';
vscodeApp = await LaunchVSCodePage.launchVSCode(executablePath);
});

test.afterAll(async () => {
await vscodeApp.closeVSCode();
});

test('should launch VSCode and check window title', async () => {
const window = vscodeApp.getWindow();
const title = await window.title();
expect(title).toContain('Visual Studio Code');
});

test('should open Extensions tab and verify installed extension', async () => {
const window = vscodeApp.getWindow();
const kaiTab = await window.getByRole('tab', { name: 'KAI', exact: true });
await kaiTab.click();
// Assert if KAI explorer is opened.
const title = await window.getByRole('heading', {
name: 'KAI',
exact: true,
});
expect(title).toBeTruthy();
});
});
111 changes: 111 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
{
"devDependencies": {
"@playwright/test": "^1.48.0",
"@types/node": "^22.7.5",
"electron": "^32.2.0",
"playwright-electron": "^0.5.0",
"prettier": "^3.3.3"
},
"scripts": {
"check": "prettier --check './**/*.{ts,js,json}'",
"format": "prettier --write './**/*.{ts,js,json}'"
},
"name": "kai-ci",
"version": "1.0.0",
"description": "This repository contains automated tests using Playwright to launch Visual Studio Code (VSCode) and install a specified extension from a VSIX file.",
"main": "index.js",
"directories": {
"test": "tests"
},
"dependencies": {
"agent-base": "^6.0.2",
"balanced-match": "^1.0.2",
"boolean": "^3.2.0",
"brace-expansion": "^1.1.11",
"buffer-crc32": "^0.2.13",
"cacheable-lookup": "^5.0.4",
"cacheable-request": "^7.0.4",
"clone-response": "^1.0.3",
"concat-map": "^0.0.1",
"debug": "^4.3.7",
"decompress-response": "^6.0.0",
"defer-to-connect": "^2.0.1",
"define-data-property": "^1.1.4",
"define-properties": "^1.2.1",
"detect-node": "^2.1.0",
"dotenv": "^16.4.5",
"end-of-stream": "^1.4.4",
"env-paths": "^2.2.1",
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"es6-error": "^4.1.1",
"escape-string-regexp": "^4.0.0",
"extract-zip": "^2.0.1",
"fd-slicer": "^1.1.0",
"fs-extra": "^8.1.0",
"fs.realpath": "^1.0.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"get-stream": "^5.2.0",
"glob": "^7.2.3",
"global-agent": "^3.0.0",
"globalthis": "^1.0.4",
"gopd": "^1.0.1",
"got": "^11.8.6",
"graceful-fs": "^4.2.11",
"has-property-descriptors": "^1.0.2",
"has-proto": "^1.0.3",
"has-symbols": "^1.0.3",
"hasown": "^2.0.2",
"http-cache-semantics": "^4.1.1",
"http2-wrapper": "^1.0.3",
"https-proxy-agent": "^5.0.1",
"inflight": "^1.0.6",
"inherits": "^2.0.4",
"jpeg-js": "^0.4.4",
"json-buffer": "^3.0.1",
"json-stringify-safe": "^5.0.1",
"jsonfile": "^4.0.0",
"keyv": "^4.5.4",
"lowercase-keys": "^2.0.0",
"matcher": "^3.0.0",
"mime": "^2.6.0",
"mimic-response": "^1.0.1",
"minimatch": "^3.1.2",
"ms": "^2.1.3",
"normalize-url": "^6.1.0",
"object-keys": "^1.1.1",
"once": "^1.4.0",
"p-cancelable": "^2.1.1",
"path-is-absolute": "^1.0.1",
"pend": "^1.2.0",
"playwright": "^1.48.0",
"playwright-core": "^1.48.0",
"pngjs": "^5.0.0",
"progress": "^2.0.3",
"proper-lockfile": "^4.1.2",
"proxy-from-env": "^1.1.0",
"pump": "^3.0.2",
"quick-lru": "^5.1.1",
"resolve-alpn": "^1.2.1",
"responselike": "^2.0.1",
"retry": "^0.12.0",
"rimraf": "^3.0.2",
"roarr": "^2.15.4",
"semver": "^6.3.1",
"semver-compare": "^1.0.0",
"serialize-error": "^7.0.1",
"signal-exit": "^3.0.7",
"sprintf-js": "^1.1.3",
"sumchecker": "^3.0.1",
"type-fest": "^0.13.1",
"undici-types": "^6.19.8",
"universalify": "^0.1.2",
"wrappy": "^1.0.2",
"ws": "^7.5.10",
"yauzl": "^2.10.0"
},
"keywords": [],
"author": "",
"license": "ISC"
}
19 changes: 19 additions & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { defineConfig } from '@playwright/test';
import dotenv from 'dotenv';

import path from 'path';
dotenv.config({ path: path.resolve(__dirname, '.env') });

export default defineConfig({
testDir: './e2e/tests',

fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: 'html',

use: {
trace: 'on-first-retry',
},
});
File renamed without changes.

0 comments on commit 9255d4a

Please sign in to comment.