Skip to content

Commit c0ce037

Browse files
Merge pull request #17 from qavajs/test-repository
added test explorer added page object explorer
2 parents 57b1437 + 7e39fee commit c0ce037

File tree

10 files changed

+871
-391
lines changed

10 files changed

+871
-391
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ All notable changes to the "qavajs" extension will be documented in this file.
44

55
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
66

7+
## [0.6.0]
8+
9+
- Addded test explorer support
10+
- Added page object tree view
11+
712
## [0.5.4]
813

914
- Addded logic go invalidate import cache for page objects

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This is extension based on Cucumber official plugin and enables support of qavaj
44

55
## Features
66

7-
- Run single scenario
7+
- VSCode Test Explorer
88
- Template Autocomplete
99
- Constants Autocomplete
1010
- Page Object Autocomplete

package-lock.json

Lines changed: 355 additions & 346 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "qavajs",
33
"displayName": "qavajs",
44
"description": "qavajs test automation framework vscode extension",
5-
"version": "0.5.4",
5+
"version": "0.6.0",
66
"engines": {
77
"vscode": "^1.78.0"
88
},
@@ -17,15 +17,48 @@
1717
"contributes": {
1818
"commands": [
1919
{
20-
"command": "qavajs.execute",
21-
"title": "qavajs run"
20+
"command": "pageObject.refresh",
21+
"title": "Refresh",
22+
"icon": "$(timeline-refresh)"
23+
},
24+
{
25+
"command": "pageObject.copy",
26+
"title": "Copy Path",
27+
"icon": "$(explorer-view-icon)"
2228
}
2329
],
30+
"viewsContainers": {
31+
"activitybar": [
32+
{
33+
"id": "page-object",
34+
"title": "qavajs",
35+
"icon": "$(symbol-class)"
36+
}
37+
]
38+
},
39+
"views": {
40+
"page-object": [
41+
{
42+
"id": "pageObject",
43+
"name": "Page Object",
44+
"icon": "$(symbol-class)",
45+
"contextualTitle": "page objects"
46+
}
47+
]
48+
},
2449
"menus": {
25-
"editor/context": [
50+
"view/title": [
51+
{
52+
"command": "pageObject.refresh",
53+
"when": "view == pageObject",
54+
"group": "navigation"
55+
}
56+
],
57+
"view/item/context": [
2658
{
27-
"command": "qavajs.execute",
28-
"when": "resourceExtname == .feature"
59+
"command": "pageObject.copy",
60+
"when": "view == pageObject",
61+
"group": "inline"
2962
}
3063
]
3164
},
@@ -95,6 +128,7 @@
95128
"repository": "https://github.com/qavajs/vscode.git",
96129
"scripts": {
97130
"vsce": "vsce package",
131+
"prevsce": "npm run package",
98132
"vscode:prepublish": "npm run package",
99133
"compile": "webpack",
100134
"watch": "webpack --watch",
@@ -107,19 +141,19 @@
107141
"copy-wasms": "mkdir -p dist && cp node_modules/@cucumber/language-service/dist/*.wasm dist"
108142
},
109143
"devDependencies": {
110-
"@types/mocha": "^10.0.4",
144+
"@types/mocha": "^10.0.6",
111145
"@types/node": "^18.0.0",
112146
"@types/vscode": "^1.78.0",
113-
"@typescript-eslint/eslint-plugin": "^6.10.0",
114-
"@typescript-eslint/parser": "^6.10.0",
115-
"@vscode/test-electron": "^2.3.6",
147+
"@typescript-eslint/eslint-plugin": "^7.0.1",
148+
"@typescript-eslint/parser": "^7.0.1",
149+
"@vscode/test-electron": "^2.3.9",
116150
"@vscode/vsce": "^2.23.0",
117-
"eslint": "^8.53.0",
151+
"eslint": "^8.56.0",
118152
"glob": "^10.3.10",
119-
"mocha": "^10.2.0",
153+
"mocha": "^10.3.0",
120154
"ts-loader": "^9.5.1",
121155
"typescript": "^5.3.3",
122-
"webpack": "^5.89.0",
156+
"webpack": "^5.90.2",
123157
"webpack-cli": "^5.1.4"
124158
},
125159
"dependencies": {

src/PageObjectTreeDataProvider.ts

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import * as vscode from 'vscode';
2+
import * as path from 'path';
3+
import { importFile } from './importFile';
4+
5+
export class PageObjectTreeDataProvider implements vscode.TreeDataProvider<PageObjectItem> {
6+
constructor(private poPath: string) { }
7+
8+
private _onDidChangeTreeData: vscode.EventEmitter<PageObjectItem | undefined | null | void> = new vscode.EventEmitter<PageObjectItem | undefined | null | void>();
9+
readonly onDidChangeTreeData: vscode.Event<PageObjectItem | undefined | null | void> = this._onDidChangeTreeData.event;
10+
11+
refresh(): void {
12+
this._onDidChangeTreeData.fire();
13+
}
14+
15+
getTreeItem(element: PageObjectItem): vscode.TreeItem {
16+
return element;
17+
}
18+
19+
getChildren(element?: PageObjectItem): Thenable<PageObjectItem[]> {
20+
if (this.poPath && vscode.workspace.workspaceFolders) {
21+
const cwd = vscode.workspace.workspaceFolders[0].uri.fsPath;
22+
const absolutePoPath = path.join(cwd, this.poPath);
23+
return importFile(absolutePoPath).then(po => {
24+
if (po.default) po = po.default;
25+
const data = typeof po === 'function' ? new po() : po;
26+
27+
if (element) {
28+
const component = element.parent[element.label];
29+
return this.getComponentProperties(component).map(
30+
([poKey, poValue]: [string, any]) => new PageObjectItem({
31+
label: poKey,
32+
locator: poValue.selector,
33+
parent: component,
34+
isComponent: this.isComponent(poValue),
35+
path: `${element.path} > ${this.normalizePath(poKey)}`,
36+
isColleciton: poValue.isCollection
37+
})
38+
)
39+
} else {
40+
return this.getComponentProperties(data).map(
41+
([poKey, poValue]: [string, any]) => new PageObjectItem({
42+
label: poKey,
43+
locator: poValue.selector,
44+
parent: data,
45+
isComponent: this.isComponent(poValue),
46+
path: this.normalizePath(poKey),
47+
isColleciton: poValue.isCollection
48+
})
49+
)
50+
}
51+
});
52+
}
53+
return Promise.resolve([]);
54+
}
55+
56+
getComponentProperties(obj: Object) {
57+
return Object.entries(obj).filter(([prop]) => ![
58+
'isCollection',
59+
'ignoreHierarchy',
60+
'selector'
61+
].includes(prop))
62+
}
63+
64+
isComponent(obj: Object) {
65+
return this.getComponentProperties(obj).length > 0
66+
}
67+
68+
normalizePath(label: string) {
69+
return label.replace(/([A-Z])/g, ' $1').trim().replace(/\s+/g, ' ')
70+
}
71+
}
72+
73+
class PageObjectItem extends vscode.TreeItem {
74+
public readonly label: string;
75+
private locator: string;
76+
public parent: any;
77+
public isComponent: boolean;
78+
public path: string;
79+
public isColleciton: boolean;
80+
81+
constructor({
82+
label,
83+
locator,
84+
parent,
85+
isComponent,
86+
path,
87+
isColleciton
88+
}: {
89+
label: string,
90+
locator: string,
91+
parent: any,
92+
isComponent: boolean,
93+
path: string,
94+
isColleciton: boolean
95+
}) {
96+
const collapsibleState = isComponent
97+
? vscode.TreeItemCollapsibleState.Collapsed
98+
: vscode.TreeItemCollapsibleState.None;
99+
100+
super(label, collapsibleState);
101+
this.label = label;
102+
this.locator = locator;
103+
this.parent = parent;
104+
this.isComponent = isComponent;
105+
this.description = this.locator;
106+
this.path = path;
107+
this.tooltip = this.path;
108+
this.isColleciton = isColleciton;
109+
110+
this.iconPath = this.isComponent
111+
? new vscode.ThemeIcon('symbol-class')
112+
: new vscode.ThemeIcon('symbol-interface');
113+
}
114+
115+
}

src/executeCommand.ts

Lines changed: 0 additions & 29 deletions
This file was deleted.

src/extension.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as vscode from 'vscode';
22
import poAutocomplete from './qavaAutocomplete';
3-
import executeCommand from './executeCommand';
3+
import testExplorer from './testExplorer';
4+
import pageObjectTreeView from './pageObjectTreeView';
45

56
import { startEmbeddedServer } from './startEmbeddedServer'
67
import { LanguageClient, LanguageClientOptions, ServerOptions } from 'vscode-languageclient/node'
@@ -11,8 +12,9 @@ let client: LanguageClient
1112
// This method is called when your extension is activated
1213
// Your extension is activated the very first time the command is executed
1314
export async function activate(context: vscode.ExtensionContext) {
14-
executeCommand(context);
15+
testExplorer(context);
1516
poAutocomplete(context);
17+
pageObjectTreeView(context);
1618

1719
const serverOptions: ServerOptions = async () =>
1820
startEmbeddedServer(

src/pageObjectTreeView.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import * as vscode from 'vscode';
2+
import { PageObjectTreeDataProvider } from './PageObjectTreeDataProvider';
3+
4+
export default async function activate(context: vscode.ExtensionContext) {
5+
const config = vscode.workspace.getConfiguration('qavajs');
6+
const poPath: string | undefined = config.get('pageObject');
7+
8+
vscode.window.registerTreeDataProvider(
9+
'pageObject',
10+
new PageObjectTreeDataProvider(poPath as string)
11+
);
12+
13+
const treeDataProvider = new PageObjectTreeDataProvider(poPath as string);
14+
vscode.window.createTreeView('pageObject', { treeDataProvider });
15+
16+
context.subscriptions.push(vscode.commands.registerCommand('pageObject.copy', (pageObjectItem) => {
17+
return vscode.env.clipboard.writeText(pageObjectItem.path)
18+
}));
19+
20+
context.subscriptions.push(vscode.commands.registerCommand('pageObject.refresh', () => {
21+
return treeDataProvider.refresh();
22+
}));
23+
}

0 commit comments

Comments
 (0)