Skip to content

Commit

Permalink
Update creator webviews to reflect ansible-creator CLI changes (#1582)
Browse files Browse the repository at this point in the history
Adds a check for the ansible-creator version, as ansible-creator v24.10.0 is required for ansible-creator's new CLI structure to work with ADT server. 

Changes any reference of "scm-org" to "namespace" and "scm-project" to "collection". 

Adds a UI test for the Create Ansible Project Page webview.

Adds the "semver" dependency to do version comparison for ansible-creator.
  • Loading branch information
alisonlhart authored Oct 17, 2024
1 parent 5c40c83 commit 42d1aaa
Show file tree
Hide file tree
Showing 11 changed files with 152 additions and 33 deletions.
4 changes: 2 additions & 2 deletions media/contentCreator/createAnsibleProjectPageStyle.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ vscode-text-area {
margin-bottom: 6px;
}

.scm-org-project-div {
.playbook-project-div {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}

#scm-org-name, #scm-project-name {
#namespace-name, #collection-name {
width:49%;
display:inline-block;
}
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,7 @@
"ini": "^4.1.3",
"marked": "^13.0.3",
"minimatch": "^9.0.5",
"semver": "^7.6.3",
"start-server-and-test": "^2.0.5",
"uuid": "^10.0.0",
"vscode-languageclient": "^9.0.1",
Expand Down
2 changes: 2 additions & 0 deletions src/definitions/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,5 @@ export const IncludeVarValidTaskName = [
];

export const ANSIBLE_LIGHTSPEED_API_TIMEOUT = 50000;

export const ANSIBLE_CREATOR_VERSION_MIN = "24.10.0";
2 changes: 1 addition & 1 deletion src/features/contentCreator/createAnsibleCollectionPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ export class CreateAnsibleCollection {
? initPath
: `${os.homedir()}/.ansible/collections/ansible_collections`;

let ansibleCreatorInitCommand = `ansible-creator init ${namespaceName}.${collectionName} --init-path=${initPathUrl} --no-ansi`;
let ansibleCreatorInitCommand = `ansible-creator init collection ${namespaceName}.${collectionName} ${initPathUrl} --no-ansi`;

// adjust collection url for using it in ade and opening it in workspace
// NOTE: this is done in order to synchronize the behavior of ade and extension
Expand Down
43 changes: 35 additions & 8 deletions src/features/contentCreator/createAnsibleProjectPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@

import * as vscode from "vscode";
import * as os from "os";
import * as semver from "semver";
import { getUri } from "../utils/getUri";
import { getNonce } from "../utils/getNonce";
import { AnsibleProjectFormInterface, PostMessageEvent } from "./types";
import { withInterpreter } from "../utils/commandRunner";
import { SettingsManager } from "../../settings";
import { expandPath, runCommand } from "./utils";
import { expandPath, getBinDetail, runCommand } from "./utils";
import { ANSIBLE_CREATOR_VERSION_MIN } from "../../definitions/constants";

export class CreateAnsibleProject {
public static currentPanel: CreateAnsibleProject | undefined;
private readonly _panel: vscode.WebviewPanel;
private _disposables: vscode.Disposable[] = [];
public static readonly viewType = "CreateProject";

private constructor(panel: vscode.WebviewPanel, extensionUri: vscode.Uri) {
this._panel = panel;
Expand Down Expand Up @@ -128,9 +131,9 @@ export class CreateAnsibleProject {
</section>
</vscode-text-field>
<div class="scm-org-project-div">
<vscode-text-field id="scm-org-name" form="init-form" placeholder="Enter scm organization name" size="512">SCM organization *</vscode-text-field>
<vscode-text-field id="scm-project-name" form="init-form" placeholder="Enter scm project name" size="512">SCM project *</vscode-text-field>
<div class="playbook-project-div">
<vscode-text-field id="namespace-name" form="init-form" placeholder="Enter namespace name" size="512">Namespace *</vscode-text-field>
<vscode-text-field id="collection-name" form="init-form" placeholder="Enter collection name" size="512">Collection *</vscode-text-field>
</div>
<div id="full-collection-path" class="full-collection-path">
Expand Down Expand Up @@ -277,6 +280,26 @@ export class CreateAnsibleProject {
);
}

// Get ansible-creator version and check which command should be used
public async getCreatorCommand(
namespace: string,
collection: string,
url: string,
): Promise<string> {
let command = "";
const creatorVersion = (
await getBinDetail("ansible-creator", "--version")
).toString();
console.log("ansible-creator version: ", creatorVersion);

if (semver.gte(creatorVersion, ANSIBLE_CREATOR_VERSION_MIN)) {
command = `ansible-creator init playbook ${namespace}.${collection} ${url} --no-ansi`;
} else {
command = `ansible-creator init --project=ansible-project --init-path=${url} --scm-org=${namespace} --scm-project=${collection} --no-ansi`;
}
return command;
}

public async openExplorerDialog(
selectOption: string,
): Promise<string | undefined> {
Expand Down Expand Up @@ -304,8 +327,8 @@ export class CreateAnsibleProject {
) {
const {
destinationPath,
scmOrgName,
scmProjectName,
namespaceName,
collectionName,
logToFile,
logFilePath,
logFileAppend,
Expand All @@ -316,9 +339,13 @@ export class CreateAnsibleProject {

const destinationPathUrl = destinationPath
? destinationPath
: `${os.homedir()}/${scmOrgName}-${scmProjectName}`;
: `${os.homedir()}/${namespaceName}-${collectionName}`;

let ansibleCreatorInitCommand = `ansible-creator init --project=ansible-project --init-path=${destinationPathUrl} --scm-org=${scmOrgName} --scm-project=${scmProjectName} --no-ansi`;
let ansibleCreatorInitCommand = await this.getCreatorCommand(
namespaceName,
collectionName,
destinationPathUrl,
);

if (isForced) {
ansibleCreatorInitCommand += " --force";
Expand Down
4 changes: 2 additions & 2 deletions src/features/contentCreator/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export type AnsibleCollectionFormInterface = {

export type AnsibleProjectFormInterface = {
destinationPath: string;
scmOrgName: string;
scmProjectName: string;
namespaceName: string;
collectionName: string;
verbosity: string;
logToFile: boolean;
logFilePath: string;
Expand Down
34 changes: 18 additions & 16 deletions src/webview/apps/contentCreator/createAnsibleProjectPageApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ window.addEventListener("load", main);
let destinationPathUrlTextField: TextField;
let folderExplorerButton: Button;

let scmOrgNameTextField: TextField;
let scmProjectNameTextField: TextField;
let namespaceNameTextField: TextField;
let collectionNameTextField: TextField;

let initCreateButton: Button;
let initClearButton: Button;
Expand Down Expand Up @@ -59,9 +59,11 @@ function main() {
) as TextField;
folderExplorerButton = document.getElementById("folder-explorer") as Button;

scmOrgNameTextField = document.getElementById("scm-org-name") as TextField;
scmProjectNameTextField = document.getElementById(
"scm-project-name",
namespaceNameTextField = document.getElementById(
"namespace-name",
) as TextField;
collectionNameTextField = document.getElementById(
"collection-name",
) as TextField;

forceCheckbox = document.getElementById("force-checkbox") as Checkbox;
Expand Down Expand Up @@ -96,8 +98,8 @@ function main() {

// projectNameTextField?.addEventListener("input", toggleCreateButton);
destinationPathUrlTextField.addEventListener("input", toggleCreateButton);
scmOrgNameTextField.addEventListener("input", toggleCreateButton);
scmProjectNameTextField.addEventListener("input", toggleCreateButton);
namespaceNameTextField.addEventListener("input", toggleCreateButton);
collectionNameTextField.addEventListener("input", toggleCreateButton);

folderExplorerButton.addEventListener("click", openExplorer);
fileExplorerButton.addEventListener("click", openExplorer);
Expand Down Expand Up @@ -166,11 +168,11 @@ function toggleCreateButton() {
if (!destinationPathUrlTextField.value.trim()) {
initCollectionPathElement.innerHTML = `${
destinationPathUrlTextField.placeholder
}/${scmOrgNameTextField.value.trim()}-${scmProjectNameTextField.value.trim()}`;
}/${namespaceNameTextField.value.trim()}-${collectionNameTextField.value.trim()}`;

if (
!scmOrgNameTextField.value.trim() ||
!scmProjectNameTextField.value.trim()
!namespaceNameTextField.value.trim() ||
!collectionNameTextField.value.trim()
) {
initCollectionPathElement.innerHTML =
destinationPathUrlTextField.placeholder;
Expand All @@ -181,8 +183,8 @@ function toggleCreateButton() {
}

if (
scmOrgNameTextField.value.trim() &&
scmProjectNameTextField.value.trim()
namespaceNameTextField.value.trim() &&
collectionNameTextField.value.trim()
) {
initCreateButton.disabled = false;
} else {
Expand All @@ -193,8 +195,8 @@ function toggleCreateButton() {
function handleInitClearClick() {
// projectNameTextField.value = "";
destinationPathUrlTextField.value = "";
scmOrgNameTextField.value = "";
scmProjectNameTextField.value = "";
namespaceNameTextField.value = "";
collectionNameTextField.value = "";

initCollectionPathElement.innerHTML = destinationPathUrlTextField.placeholder;

Expand Down Expand Up @@ -232,8 +234,8 @@ function handleInitCreateClick() {
payload: {
// projectName: projectNameTextField.value.trim(),
destinationPath: destinationPathUrlTextField.value.trim(),
scmOrgName: scmOrgNameTextField.value.trim(),
scmProjectName: scmProjectNameTextField.value.trim(),
namespaceName: namespaceNameTextField.value.trim(),
collectionName: collectionNameTextField.value.trim(),
verbosity: verboseDropdown.currentValue.trim(),
logToFile: logToFileCheckbox.checked,
logFilePath: logFilePath.value.trim(),
Expand Down
2 changes: 2 additions & 0 deletions test/ui-test/allTestsSuite.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { contentCreatorUiTest } from "./contentCreatorUiTest";
import { extensionUIAssetsTest } from "./extensionUITest";
import { lightspeedUILoginTest } from "./lightspeedAuthUiTest";
import { lightspeedOneClickTrialUITest } from "./lightspeedOneClickTrialUITest";
Expand All @@ -22,4 +23,5 @@ describe("VSCode Ansible - UI tests", function () {
// lightspeedUISignOutTest();
}
walkthroughUiTest();
contentCreatorUiTest();
});
78 changes: 78 additions & 0 deletions test/ui-test/contentCreatorUiTest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import {
By,
EditorView,
WebElement,
WebView,
Workbench,
} from "vscode-extension-tester";
import { sleep } from "./uiTestHelper";
import { config, expect } from "chai";

config.truncateThreshold = 0;
export function contentCreatorUiTest(): void {
describe("Test Ansible playbook project scaffolding", () => {
let workbench: Workbench;
let createButton: WebElement;
let editorView: EditorView;

before(async () => {
workbench = new Workbench();
editorView = new EditorView();
if (editorView) {
await editorView.closeAllEditors();
}
});

it("Check create-ansible-project webview elements", async () => {
await workbench.executeCommand("Ansible: Create New Playbook Project");
await sleep(4000);

const playbookProject = (await new EditorView().openEditor(
"Create Ansible project",
)) as WebView;

expect(playbookProject, "webView should not be undefined").not.to.be
.undefined;
await playbookProject.switchToFrame(5000);
expect(
playbookProject,
"webView should not be undefined after switching to its frame",
).not.to.be.undefined;

const namespaceTextField = await playbookProject.findWebElement(
By.xpath("//vscode-text-field[@id='namespace-name']"),
);
expect(namespaceTextField, "namespaceTextField should not be undefined")
.not.to.be.undefined;
await namespaceTextField.sendKeys("test_namespace");

const collectionTextField = await playbookProject.findWebElement(
By.xpath("//vscode-text-field[@id='collection-name']"),
);
expect(collectionTextField, "collectionTextField should not be undefined")
.not.to.be.undefined;
await collectionTextField.sendKeys("test_collection");

const forceCheckbox = await playbookProject.findWebElement(
By.xpath("//vscode-checkbox[@id='force-checkbox']"),
);

expect(forceCheckbox, "forceCheckbox should not be undefined").not.to.be
.undefined;
await forceCheckbox.click();

createButton = await playbookProject.findWebElement(
By.xpath("//vscode-button[@id='create-button']"),
);
expect(createButton, "createButton should not be undefined").not.to.be
.undefined;

expect(
await createButton.isEnabled(),
"Create button should be enabled now",
).to.be.true;
await createButton.click();
await playbookProject.switchBack();
});
});
}
6 changes: 6 additions & 0 deletions test/units/contentCreator/utilities.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ const getBinDetailTests = [
arg: "--version",
expected: "failed",
},
{
name: "valid binary (ansible-creator)",
command: "ansible-creator",
arg: "--version",
expected: "ansible-creator",
},
];

const runCommandTests = [
Expand Down
9 changes: 5 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2333,6 +2333,7 @@ __metadata:
react: "npm:^18.3.1"
rimraf: "npm:^5.0.9"
selenium-webdriver: "npm:^4.23.0"
semver: "npm:^7.6.3"
shiki: "npm:^1.12.0"
sinon: "npm:^18.0.0"
start-server-and-test: "npm:^2.0.5"
Expand Down Expand Up @@ -8882,12 +8883,12 @@ __metadata:
languageName: node
linkType: hard

"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.2":
version: 7.6.2
resolution: "semver@npm:7.6.2"
"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.2, semver@npm:^7.6.3":
version: 7.6.3
resolution: "semver@npm:7.6.3"
bin:
semver: bin/semver.js
checksum: 10/296b17d027f57a87ef645e9c725bff4865a38dfc9caf29b26aa084b85820972fbe7372caea1ba6857162fa990702c6d9c1d82297cecb72d56c78ab29070d2ca2
checksum: 10/36b1fbe1a2b6f873559cd57b238f1094a053dbfd997ceeb8757d79d1d2089c56d1321b9f1069ce263dc64cfa922fa1d2ad566b39426fe1ac6c723c1487589e10
languageName: node
linkType: hard

Expand Down

0 comments on commit 42d1aaa

Please sign in to comment.