From 883d49dfc0010c0758f4915007334229d6448ab2 Mon Sep 17 00:00:00 2001
From: Ajinkya Udgirkar <ajinkyaudgirkar@gmail.com>
Date: Fri, 4 Oct 2024 13:11:51 +0530
Subject: [PATCH] Add welcome page and update the title (#1475)

* Code refactor and welcome page title update

* ui tests for welcome page

* Fix function name casing

* Code refactor and welcome page title update

* ui tests for welcome page

* Fix function name casing

* fix for lightspeed one click trial and auth test failure

* Revert lightspeed test related changes

* Remove duplicate code

* Remove spacing

* Skip tests for lightspeed one click trial feature

* Update welcome page tests

* Skip tests for lightspeed one click trial feature

* Test container cleanup commands update
---
 .../style.css}                                |   4 +
 package.json                                  |   4 +-
 src/extension.ts                              |   4 +-
 src/features/contentCreator/welcomePage.ts    | 283 ----------------
 .../playbookGeneration/welcomePage.ts         | 309 ------------------
 src/features/welcomePage/index.ts             | 309 ++++++++++++++++++
 .../welcomePageApp.ts                         |   0
 test/ui-test/allTestsSuite.ts                 |   2 +
 test/ui-test/lightspeedUiTest.ts              |   6 +-
 test/ui-test/welcomePageUITest.ts             |  92 ++++++
 webpack.config.ts                             |   4 +-
 11 files changed, 416 insertions(+), 601 deletions(-)
 rename media/{playbookGeneration/playbookGeneration.css => welcomePage/style.css} (97%)
 delete mode 100644 src/features/contentCreator/welcomePage.ts
 delete mode 100644 src/features/playbookGeneration/welcomePage.ts
 create mode 100644 src/features/welcomePage/index.ts
 rename src/webview/apps/{contentCreator => welcomePage}/welcomePageApp.ts (100%)
 create mode 100644 test/ui-test/welcomePageUITest.ts

diff --git a/media/playbookGeneration/playbookGeneration.css b/media/welcomePage/style.css
similarity index 97%
rename from media/playbookGeneration/playbookGeneration.css
rename to media/welcomePage/style.css
index 1633f42b6..c54f2c918 100644
--- a/media/playbookGeneration/playbookGeneration.css
+++ b/media/welcomePage/style.css
@@ -243,3 +243,7 @@ a .codicon {
 	border-style: solid;
 	border-radius: 4px;
 }
+
+.playbookGenerationContainer .playbookGenerationSlideCategories>.playbookGenerationCategoriesContainer > .header > .subtitle {
+	font-size: 1em;
+}
diff --git a/package.json b/package.json
index 0d413f85a..715e3de7f 100644
--- a/package.json
+++ b/package.json
@@ -150,7 +150,7 @@
       "ansible-explorer": [
         {
           "id": "ansible-content-creator",
-          "name": "Ansible content creator"
+          "name": "Ansible Development Tools"
         },
         {
           "id": "lightspeed-explorer-webview",
@@ -296,7 +296,7 @@
       },
       {
         "command": "ansible.content-creator.menu",
-        "title": "Open Ansible Content Creator menu"
+        "title": "Open Ansible Development Tools menu"
       },
       {
         "command": "ansible.content-creator.install",
diff --git a/src/extension.ts b/src/extension.ts
index 90fa27e53..ab3f29af2 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -56,7 +56,7 @@ import { AnsibleToxProvider } from "./features/ansibleTox/provider";
 import { findProjectDir } from "./features/ansibleTox/utils";
 import { LightspeedFeedbackWebviewViewProvider } from "./features/lightspeed/feedbackWebviewViewProvider";
 import { LightspeedFeedbackWebviewProvider } from "./features/lightspeed/feedbackWebviewProvider";
-import { AnsibleCreatorMenu } from "./features/playbookGeneration/welcomePage";
+import { AnsibleWelcomePage } from "./features/welcomePage";
 import { CreateAnsibleCollection } from "./features/contentCreator/createAnsibleCollectionPage";
 import { withInterpreter } from "./features/utils/commandRunner";
 import { IFileSystemWatchers } from "./interfaces/watchers";
@@ -502,7 +502,7 @@ export async function activate(context: ExtensionContext): Promise<void> {
   // open ansible-content-creator menu
   context.subscriptions.push(
     vscode.commands.registerCommand("ansible.content-creator.menu", () => {
-      AnsibleCreatorMenu.render(context.extensionUri);
+      AnsibleWelcomePage.render(context.extensionUri);
     }),
   );
 
diff --git a/src/features/contentCreator/welcomePage.ts b/src/features/contentCreator/welcomePage.ts
deleted file mode 100644
index 85dec977d..000000000
--- a/src/features/contentCreator/welcomePage.ts
+++ /dev/null
@@ -1,283 +0,0 @@
-/* eslint-disable  @typescript-eslint/no-explicit-any */
-
-import * as vscode from "vscode";
-import { getUri } from "../utils/getUri";
-import { getNonce } from "../utils/getNonce";
-import * as ini from "ini";
-import { getBinDetail } from "./utils";
-
-export class AnsibleCreatorMenu {
-  public static currentPanel: AnsibleCreatorMenu | undefined;
-  private readonly _panel: vscode.WebviewPanel;
-  private _disposables: vscode.Disposable[] = [];
-
-  private constructor(panel: vscode.WebviewPanel, extensionUri: vscode.Uri) {
-    this._panel = panel;
-    this._panel.webview.html = this._getWebviewContent(
-      this._panel.webview,
-      extensionUri,
-    );
-    this._setWebviewMessageListener(this._panel.webview);
-    this._panel.onDidDispose(() => this.dispose(), null, this._disposables);
-  }
-
-  public static render(extensionUri: vscode.Uri) {
-    if (AnsibleCreatorMenu.currentPanel) {
-      AnsibleCreatorMenu.currentPanel._panel.reveal(vscode.ViewColumn.One);
-    } else {
-      const panel = vscode.window.createWebviewPanel(
-        "content-creator-menu",
-        "Ansible Content Creator",
-        vscode.ViewColumn.One,
-        {
-          enableScripts: true,
-          localResourceRoots: [
-            vscode.Uri.joinPath(extensionUri, "out"),
-            vscode.Uri.joinPath(extensionUri, "media"),
-          ],
-          enableCommandUris: true,
-          retainContextWhenHidden: true,
-        },
-      );
-
-      AnsibleCreatorMenu.currentPanel = new AnsibleCreatorMenu(
-        panel,
-        extensionUri,
-      );
-    }
-  }
-
-  public dispose() {
-    AnsibleCreatorMenu.currentPanel = undefined;
-
-    this._panel.dispose();
-
-    while (this._disposables.length) {
-      const disposable = this._disposables.pop();
-      if (disposable) {
-        disposable.dispose();
-      }
-    }
-  }
-
-  private _getWebviewContent(
-    webview: vscode.Webview,
-    extensionUri: vscode.Uri,
-  ) {
-    const webviewUri = getUri(webview, extensionUri, [
-      "out",
-      "client",
-      "webview",
-      "apps",
-      "contentCreator",
-      "welcomePageApp.js",
-    ]);
-
-    const nonce = getNonce();
-    const styleUri = getUri(webview, extensionUri, [
-      "media",
-      "contentCreator",
-      "welcomePageStyle.css",
-    ]);
-
-    const codiconsUri = getUri(webview, extensionUri, [
-      "media",
-      "codicons",
-      "codicon.css",
-    ]);
-
-    const contentCreatorIcon = getUri(webview, extensionUri, [
-      "media",
-      "contentCreator",
-      "icons",
-      "ansible-logo-red.png",
-    ]);
-
-    const initIcon = getUri(webview, extensionUri, [
-      "media",
-      "contentCreator",
-      "icons",
-      "ansible-creator-init.png",
-    ]);
-
-    const sampleIcon = getUri(webview, extensionUri, [
-      "media",
-      "contentCreator",
-      "icons",
-      "ansible-creator-sample.png",
-    ]);
-
-    const createIcon = getUri(webview, extensionUri, [
-      "media",
-      "contentCreator",
-      "icons",
-      "ansible-creator-create.png",
-    ]);
-
-    return /*html*/ `
-      <html>
-
-        <head>
-          <meta charset="UTF-8" />
-          <meta name="viewport" content="width=device-width, initial-scale=1.0">
-          <meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'nonce-${nonce}'; style-src ${webview.cspSource}; font-src ${webview.cspSource}; img-src ${webview.cspSource};">
-          <title>AAA</title>
-          <link rel="stylesheet" href="${styleUri}">
-          <link rel="stylesheet" href="${codiconsUri}">
-        </head>
-
-        <body>
-          <div class="intro">
-            <div class="heading">
-              <img src="${contentCreatorIcon}" alt="Ansible Creator Icon">
-              <h1>nsible Content Creator</h1>
-            </div>
-
-            <p>A tool for scaffolding ansible content.
-              <vscode-link href="https://github.com/ansible-community/ansible-creator#ansible-creator">Read our docs</vscode-link>
-              to learn more about this tool.</p>
-
-            <div id="system-check">
-              <div class="icon">
-                <p>System requirements:</p>
-              </div>
-
-              <div id=install-status></div>
-
-              <div class="refresh-button-div">
-                <vscode-button id="refresh">
-                  <span class="codicon codicon-refresh"></span>
-                  &nbsp; Refresh
-                </vscode-button>
-              </div>
-
-            </div>
-          </div>
-
-          <vscode-divider role="presentation"></vscode-divider>
-
-          <div class="menu">
-            <div class="menu-item">
-              <vscode-link href="command:ansible.content-creator.create-ansible-collection">
-                <img src="${initIcon}" alt="Ansible Creator Icon">
-              </vscode-link>
-                <p class="menu-item-heading">Initialize ansible collection</p>
-            </div>
-
-            <div class="menu-item">
-              <vscode-link href="command:ansible.lightspeed.playbookGeneration">
-                <img src="${createIcon}" alt="Ansible Creator Icon">
-              </vscode-link>
-                <p class="menu-item-heading">Create ansible content</p>
-            </div>
-
-            <div class="menu-item">
-              <vscode-link href="command:ansible.content-creator.sample">
-                <img src="${sampleIcon}" alt="Ansible Creator Icon">
-              </vscode-link>
-                <p class="menu-item-heading">Open sample manifest file</p>
-            </div>
-          </div>
-
-          <!-- Component registration code -->
-          <script type="module" nonce="${nonce}" src="${webviewUri}"></script>
-        </body>
-      </html>
-    `;
-  }
-
-  private _setWebviewMessageListener(webview: vscode.Webview) {
-    webview.onDidReceiveMessage(
-      async (message) => {
-        const command = message.message;
-        switch (command) {
-          case "refresh-page":
-            await this.refreshPage();
-            return;
-
-          case "set-system-status-view":
-            await this.getSystemDetails(webview);
-            return;
-        }
-      },
-      undefined,
-      this._disposables,
-    );
-  }
-
-  private async refreshPage() {
-    await vscode.commands.executeCommand(
-      "workbench.action.webview.reloadWebviewAction",
-    );
-  }
-
-  private async getSystemDetails(webView: vscode.Webview) {
-    const systemInfo: any = {};
-
-    // get ansible version and path
-    const ansibleVersion = await getBinDetail("ansible", "--version");
-    if (ansibleVersion !== "failed") {
-      const versionInfo = ini.parse(ansibleVersion.toString());
-
-      const versionInfoObjKeys = Object.keys(versionInfo);
-
-      // return empty if ansible --version fails to execute
-      if (versionInfoObjKeys.length === 0) {
-        console.debug("[ansible-creator] No version information from ansible");
-      }
-
-      const ansibleCoreVersion = versionInfoObjKeys[0].includes(" [")
-        ? versionInfoObjKeys[0].split(" [")
-        : versionInfoObjKeys[0].split(" ");
-
-      systemInfo["ansible version"] = ansibleCoreVersion[1]
-        .slice(0, -1)
-        .split(" ")
-        .pop()
-        ?.trim();
-
-      systemInfo["ansible location"] = versionInfo["executable location"];
-    }
-
-    // get python version
-    const pythonVersion = await getBinDetail("python3", "--version");
-    if (pythonVersion !== "failed") {
-      systemInfo["python version"] = pythonVersion
-        .toString()
-        .trim()
-        .split(" ")
-        .pop()
-        ?.trim();
-    }
-
-    // get python path
-    const pythonPathResult = await getBinDetail(
-      "python3",
-      '-c "import sys; print(sys.executable)"',
-    );
-    if (pythonPathResult !== "failed") {
-      systemInfo["python location"] = pythonPathResult.toString().trim();
-    }
-
-    // get ansible-creator version
-    const ansibleCreatorVersion = await getBinDetail(
-      "ansible-creator",
-      "--version",
-    );
-    if (ansibleCreatorVersion !== "failed") {
-      systemInfo["ansible-creator version"] = ansibleCreatorVersion
-        .toString()
-        .trim();
-    }
-
-    // get ansible-creator version
-    const ansibleDevEnvironmentVersion = await getBinDetail("ade", "--version");
-    if (ansibleDevEnvironmentVersion !== "failed") {
-      systemInfo["ansible-dev-environment version"] =
-        ansibleDevEnvironmentVersion.toString().trim();
-    }
-
-    // send the system details to the webview
-    webView.postMessage({ command: "systemDetails", arguments: systemInfo });
-  }
-}
diff --git a/src/features/playbookGeneration/welcomePage.ts b/src/features/playbookGeneration/welcomePage.ts
deleted file mode 100644
index db27288f0..000000000
--- a/src/features/playbookGeneration/welcomePage.ts
+++ /dev/null
@@ -1,309 +0,0 @@
-/* eslint-disable  @typescript-eslint/no-explicit-any */
-
-import * as vscode from "vscode";
-import { getUri } from "../utils/getUri";
-import { getNonce } from "../utils/getNonce";
-import * as ini from "ini";
-import { getBinDetail } from "../contentCreator/utils";
-
-export class AnsibleCreatorMenu {
-  public static currentPanel: AnsibleCreatorMenu | undefined;
-  private readonly _panel: vscode.WebviewPanel;
-  private _disposables: vscode.Disposable[] = [];
-
-  private constructor(panel: vscode.WebviewPanel, extensionUri: vscode.Uri) {
-    this._panel = panel;
-    this._panel.webview.html = this._getWebviewContent(
-      this._panel.webview,
-      extensionUri,
-    );
-    this._setWebviewMessageListener(this._panel.webview);
-    this._panel.onDidDispose(() => this.dispose(), null, this._disposables);
-  }
-
-  public static render(extensionUri: vscode.Uri) {
-    if (AnsibleCreatorMenu.currentPanel) {
-      AnsibleCreatorMenu.currentPanel._panel.reveal(vscode.ViewColumn.One);
-    } else {
-      const panel = vscode.window.createWebviewPanel(
-        "content-creator-menu",
-        "Ansible content creator",
-        vscode.ViewColumn.One,
-        {
-          enableScripts: true,
-          localResourceRoots: [
-            vscode.Uri.joinPath(extensionUri, "out"),
-            vscode.Uri.joinPath(extensionUri, "media"),
-          ],
-          enableCommandUris: true,
-          retainContextWhenHidden: true,
-        },
-      );
-
-      AnsibleCreatorMenu.currentPanel = new AnsibleCreatorMenu(
-        panel,
-        extensionUri,
-      );
-    }
-  }
-
-  public dispose() {
-    AnsibleCreatorMenu.currentPanel = undefined;
-
-    this._panel.dispose();
-
-    while (this._disposables.length) {
-      const disposable = this._disposables.pop();
-      if (disposable) {
-        disposable.dispose();
-      }
-    }
-  }
-
-  private _getWebviewContent(
-    webview: vscode.Webview,
-    extensionUri: vscode.Uri,
-  ) {
-    const webviewUri = getUri(webview, extensionUri, [
-      "out",
-      "client",
-      "webview",
-      "apps",
-      "contentCreator",
-      "welcomePageApp.js",
-    ]);
-
-    const nonce = getNonce();
-    const styleUri = getUri(webview, extensionUri, [
-      "media",
-      "playbookGeneration",
-      "playbookGeneration.css",
-    ]);
-
-    const codiconsUri = getUri(webview, extensionUri, [
-      "media",
-      "codicons",
-      "codicon.css",
-    ]);
-
-    return /*html*/ `
-    <html>
-
-<head>
-  <meta charset="UTF-8" />
-  <meta name="viewport" content="width=device-width, initial-scale=1.0">
-  <meta http-equiv="Content-Security-Policy"
-    content="default-src 'none'; script-src 'nonce-${nonce}'; style-src ${webview.cspSource}; font-src ${webview.cspSource}; img-src ${webview.cspSource};">
-  <title>AAA</title>
-  <link rel="stylesheet" href="${styleUri}">
-  <link rel="stylesheet" href="${codiconsUri}">
-</head>
-
-<body>
-  <div class="playbookGenerationContainer">
-    <div class="playbookGenerationSlideCategories">
-      <div class="playbookGenerationCategoriesContainer">
-        <div class="header">
-          <h1 class="title caption">Welcome to Ansible content creator</h1>
-          <p class="subtitle description">Create Ansible content with ease</p>
-
-          <div id="system-readiness" class="statusDisplay"></div>
-
-        </div>
-        <div class="categories-column-left">
-          <div class="index-list start-container">
-            <h2>Create</h2>
-            <div class="catalogue">
-              <h3>
-                <a href="command:ansible.lightspeed.playbookGeneration">
-                  <span class="codicon codicon-file-code"></span> Playbook with Ansible Lightspeed
-                </a>
-              </h3>
-              <p>Create a lists of tasks that automatically execute for your specified inventory or groups of hosts.</p>
-            </div>
-            <div class="catalogue">
-              <h3>
-                <a href="command:ansible.content-creator.create-ansible-project">
-                <span class="codicon codicon-file-zip"></span> Ansible playbook project
-                </a>
-              </h3>
-              <p>Create a foundational framework and structure for setting your Ansible project with playbooks, roles, variables, templates, and other files.</p>
-            </div>
-            <div class="catalogue">
-              <h3>
-                <a href="command:ansible.content-creator.create-ansible-collection">
-                <span class="codicon codicon-layers"></span> Ansible collection project
-                </a>
-              </h3>
-              <p>Create a structure for your Ansible collection that includes modules, plugins, molecule scenarios and tests.
-              </p>
-            </div>
-          </div>
-
-          <!-- <div class="index-list start-container">
-            <h2>Recent</h2>
-            <p>No recent activity</p>
-          </div> -->
-
-          <div class="index-list start-container">
-            <h2>Learn</h2>
-            <div class="catalogue">
-              <h3>
-                <a href="https://docs.ansible.com">
-                  Ansible documentation
-                  <span class="codicon codicon-link-external"></span>
-                </a>
-              </h3>
-              <p>Explore Ansible documentation, examples and more.</p>
-            </div>
-            <div class="catalogue">
-              <h3>
-                <a href="https://docs.ansible.com/ansible/latest/getting_started/index.html">
-                  Learn Ansible development
-                  <span class="codicon codicon-link-external"></span>
-                </a>
-              </h3>
-              <p>End to end course that will help you master automation development.</p>
-            </div>
-            <div class="catalogue">
-              <h3>Once you are in the YAML file:</h3>
-              <p>click Ctrl+L to fire the Ansible Lightspeed AI assistance for editing and explaining code.</p>
-            </div>
-          </div>
-
-          <div class="shadow"></div>
-          <div class="shadow"></div>
-          <div class="shadow"></div>
-        </div>
-        <div class="categories-column-right">
-          <div class="index-list getting-started">
-            <div id="system-check">
-              <div class="icon">
-                <h2>System requirements:</h2>
-              </div>
-
-              <div id=install-status class="statusDisplay"></div>
-
-              <div class="refresh-button-div">
-                <vscode-button id="refresh">
-                  <span class="codicon codicon-refresh"></span>
-                  &nbsp; Refresh
-                </vscode-button>
-              </div>
-
-            </div>
-          </div>
-          <div class="shadow"></div>
-          <div class="shadow"></div>
-          <div class="shadow"></div>
-        </div>
-        <div class="footer">
-          <p></p>
-        </div>
-      </div>
-    </div>
-  </div>
-
-  <!-- Component registration code -->
-  <script type="module" nonce="${nonce}" src="${webviewUri}"></script>
-</body>
-
-</html>
-    `;
-  }
-
-  private _setWebviewMessageListener(webview: vscode.Webview) {
-    webview.onDidReceiveMessage(
-      async (message) => {
-        const command = message.message;
-        switch (command) {
-          case "refresh-page":
-            await this.refreshPage();
-            return;
-
-          case "set-system-status-view":
-            await this.getSystemDetails(webview);
-            return;
-        }
-      },
-      undefined,
-      this._disposables,
-    );
-  }
-
-  private async refreshPage() {
-    await vscode.commands.executeCommand(
-      "workbench.action.webview.reloadWebviewAction",
-    );
-  }
-
-  private async getSystemDetails(webView: vscode.Webview) {
-    const systemInfo: any = {};
-
-    // get ansible version and path
-    const ansibleVersion = await getBinDetail("ansible", "--version");
-    if (ansibleVersion !== "failed") {
-      const versionInfo = ini.parse(ansibleVersion.toString());
-
-      const versionInfoObjKeys = Object.keys(versionInfo);
-
-      // return empty if ansible --version fails to execute
-      if (versionInfoObjKeys.length === 0) {
-        console.debug("[ansible-creator] No version information from ansible");
-      }
-
-      const ansibleCoreVersion = versionInfoObjKeys[0].includes(" [")
-        ? versionInfoObjKeys[0].split(" [")
-        : versionInfoObjKeys[0].split(" ");
-
-      systemInfo["ansible version"] = ansibleCoreVersion[1]
-        .slice(0, -1)
-        .split(" ")
-        .pop()
-        ?.trim();
-
-      systemInfo["ansible location"] = versionInfo["executable location"];
-    }
-
-    // get python version
-    const pythonVersion = await getBinDetail("python3", "--version");
-    if (pythonVersion !== "failed") {
-      systemInfo["python version"] = pythonVersion
-        .toString()
-        .trim()
-        .split(" ")
-        .pop()
-        ?.trim();
-    }
-
-    // get python path
-    const pythonPathResult = await getBinDetail(
-      "python3",
-      '-c "import sys; print(sys.executable)"',
-    );
-    if (pythonPathResult !== "failed") {
-      systemInfo["python location"] = pythonPathResult.toString().trim();
-    }
-
-    // get ansible-creator version
-    const ansibleCreatorVersion = await getBinDetail(
-      "ansible-creator",
-      "--version",
-    );
-    if (ansibleCreatorVersion !== "failed") {
-      systemInfo["ansible-creator version"] = ansibleCreatorVersion
-        .toString()
-        .trim();
-    }
-
-    // get ansible-creator version
-    const ansibleDevEnvironmentVersion = await getBinDetail("ade", "--version");
-    if (ansibleDevEnvironmentVersion !== "failed") {
-      systemInfo["ansible-dev-environment version"] =
-        ansibleDevEnvironmentVersion.toString().trim();
-    }
-
-    // send the system details to the webview
-    webView.postMessage({ command: "systemDetails", arguments: systemInfo });
-  }
-}
diff --git a/src/features/welcomePage/index.ts b/src/features/welcomePage/index.ts
new file mode 100644
index 000000000..e3ed1151f
--- /dev/null
+++ b/src/features/welcomePage/index.ts
@@ -0,0 +1,309 @@
+/* eslint-disable  @typescript-eslint/no-explicit-any */
+
+import * as vscode from "vscode";
+import { getUri } from "../utils/getUri";
+import { getNonce } from "../utils/getNonce";
+import * as ini from "ini";
+import { getBinDetail } from "../contentCreator/utils";
+
+export class AnsibleWelcomePage {
+  public static currentPanel: AnsibleWelcomePage | undefined;
+  private readonly _panel: vscode.WebviewPanel;
+  private _disposables: vscode.Disposable[] = [];
+
+  private constructor(panel: vscode.WebviewPanel, extensionUri: vscode.Uri) {
+    this._panel = panel;
+    this._panel.webview.html = this._getWebviewContent(
+      this._panel.webview,
+      extensionUri,
+    );
+    this._setWebviewMessageListener(this._panel.webview);
+    this._panel.onDidDispose(() => this.dispose(), null, this._disposables);
+  }
+
+  public static render(extensionUri: vscode.Uri) {
+    if (AnsibleWelcomePage.currentPanel) {
+      AnsibleWelcomePage.currentPanel._panel.reveal(vscode.ViewColumn.One);
+    } else {
+      const panel = vscode.window.createWebviewPanel(
+        "content-creator-menu",
+        "Ansible Development Tools",
+        vscode.ViewColumn.One,
+        {
+          enableScripts: true,
+          localResourceRoots: [
+            vscode.Uri.joinPath(extensionUri, "out"),
+            vscode.Uri.joinPath(extensionUri, "media"),
+          ],
+          enableCommandUris: true,
+          retainContextWhenHidden: true,
+        },
+      );
+
+      AnsibleWelcomePage.currentPanel = new AnsibleWelcomePage(
+        panel,
+        extensionUri,
+      );
+    }
+  }
+
+  public dispose() {
+    AnsibleWelcomePage.currentPanel = undefined;
+
+    this._panel.dispose();
+
+    while (this._disposables.length) {
+      const disposable = this._disposables.pop();
+      if (disposable) {
+        disposable.dispose();
+      }
+    }
+  }
+
+  private _getWebviewContent(
+    webview: vscode.Webview,
+    extensionUri: vscode.Uri,
+  ) {
+    const webviewUri = getUri(webview, extensionUri, [
+      "out",
+      "client",
+      "webview",
+      "apps",
+      "welcomePage",
+      "welcomePageApp.js",
+    ]);
+
+    const nonce = getNonce();
+    const styleUri = getUri(webview, extensionUri, [
+      "media",
+      "welcomePage",
+      "style.css",
+    ]);
+
+    const codiconsUri = getUri(webview, extensionUri, [
+      "media",
+      "codicons",
+      "codicon.css",
+    ]);
+
+    return /*html*/ `
+    <html>
+
+    <head>
+      <meta charset="UTF-8" />
+      <meta name="viewport" content="width=device-width, initial-scale=1.0">
+      <meta http-equiv="Content-Security-Policy"
+        content="default-src 'none'; script-src 'nonce-${nonce}'; style-src ${webview.cspSource}; font-src ${webview.cspSource}; img-src ${webview.cspSource};">
+      <title>Ansible Development Tools</title>
+      <link rel="stylesheet" href="${styleUri}">
+      <link rel="stylesheet" href="${codiconsUri}">
+    </head>
+
+    <body>
+      <div class="playbookGenerationContainer">
+        <div class="playbookGenerationSlideCategories">
+          <div class="playbookGenerationCategoriesContainer">
+            <div class="header">
+              <h1 class="title caption">Ansible Development Tools</h1>
+              <p class="subtitle description">Create, test and deploy Ansible content in your IT environment</p>
+
+              <div id="system-readiness" class="statusDisplay"></div>
+
+            </div>
+            <div class="categories-column-left">
+              <div class="index-list start-container">
+                <h2>Create</h2>
+                <div class="catalogue">
+                  <h3>
+                    <a href="command:ansible.lightspeed.playbookGeneration">
+                      <span class="codicon codicon-file-code"></span> Playbook with Ansible Lightspeed
+                    </a>
+                  </h3>
+                  <p>Create a lists of tasks that automatically execute for your specified inventory or groups of hosts.</p>
+                </div>
+                <div class="catalogue">
+                  <h3>
+                    <a href="command:ansible.content-creator.create-ansible-project">
+                    <span class="codicon codicon-file-zip"></span> Ansible playbook project
+                    </a>
+                  </h3>
+                  <p>Create a foundational framework and structure for setting your Ansible project with playbooks, roles, variables, templates, and other files.</p>
+                </div>
+                <div class="catalogue">
+                  <h3>
+                    <a href="command:ansible.content-creator.create-ansible-collection">
+                    <span class="codicon codicon-layers"></span> Ansible collection project
+                    </a>
+                  </h3>
+                  <p>Create a structure for your Ansible collection that includes modules, plugins, molecule scenarios and tests.
+                  </p>
+                </div>
+              </div>
+
+              <!-- <div class="index-list start-container">
+                <h2>Recent</h2>
+                <p>No recent activity</p>
+              </div> -->
+
+              <div class="index-list start-container">
+                <h2>Learn</h2>
+                <div class="catalogue">
+                  <h3>
+                    <a href="https://docs.ansible.com">
+                      Ansible documentation
+                      <span class="codicon codicon-link-external"></span>
+                    </a>
+                  </h3>
+                  <p>Explore Ansible documentation, examples and more.</p>
+                </div>
+                <div class="catalogue">
+                  <h3>
+                    <a href="https://docs.ansible.com/ansible/latest/getting_started/index.html">
+                      Learn Ansible development
+                      <span class="codicon codicon-link-external"></span>
+                    </a>
+                  </h3>
+                  <p>End to end course that will help you master automation development.</p>
+                </div>
+                <div class="catalogue">
+                  <h3>Once you are in the YAML file:</h3>
+                  <p>click Ctrl+L to fire the Ansible Lightspeed AI assistance for editing and explaining code.</p>
+                </div>
+              </div>
+
+              <div class="shadow"></div>
+              <div class="shadow"></div>
+              <div class="shadow"></div>
+            </div>
+            <div class="categories-column-right">
+              <div class="index-list getting-started">
+                <div id="system-check">
+                  <div class="icon">
+                    <h2>System requirements:</h2>
+                  </div>
+
+                  <div id=install-status class="statusDisplay"></div>
+
+                  <div class="refresh-button-div">
+                    <vscode-button id="refresh">
+                      <span class="codicon codicon-refresh"></span>
+                      &nbsp; Refresh
+                    </vscode-button>
+                  </div>
+
+                </div>
+              </div>
+              <div class="shadow"></div>
+              <div class="shadow"></div>
+              <div class="shadow"></div>
+            </div>
+            <div class="footer">
+              <p></p>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- Component registration code -->
+      <script type="module" nonce="${nonce}" src="${webviewUri}"></script>
+    </body>
+
+    </html>
+    `;
+  }
+
+  private _setWebviewMessageListener(webview: vscode.Webview) {
+    webview.onDidReceiveMessage(
+      async (message) => {
+        const command = message.message;
+        switch (command) {
+          case "refresh-page":
+            await this.refreshPage();
+            return;
+
+          case "set-system-status-view":
+            await this.getSystemDetails(webview);
+            return;
+        }
+      },
+      undefined,
+      this._disposables,
+    );
+  }
+
+  private async refreshPage() {
+    await vscode.commands.executeCommand(
+      "workbench.action.webview.reloadWebviewAction",
+    );
+  }
+
+  private async getSystemDetails(webView: vscode.Webview) {
+    const systemInfo: any = {};
+
+    // get ansible version and path
+    const ansibleVersion = await getBinDetail("ansible", "--version");
+    if (ansibleVersion !== "failed") {
+      const versionInfo = ini.parse(ansibleVersion.toString());
+
+      const versionInfoObjKeys = Object.keys(versionInfo);
+
+      // return empty if ansible --version fails to execute
+      if (versionInfoObjKeys.length === 0) {
+        console.debug("[ansible-creator] No version information from ansible");
+      }
+
+      const ansibleCoreVersion = versionInfoObjKeys[0].includes(" [")
+        ? versionInfoObjKeys[0].split(" [")
+        : versionInfoObjKeys[0].split(" ");
+
+      systemInfo["ansible version"] = ansibleCoreVersion[1]
+        .slice(0, -1)
+        .split(" ")
+        .pop()
+        ?.trim();
+
+      systemInfo["ansible location"] = versionInfo["executable location"];
+    }
+
+    // get python version
+    const pythonVersion = await getBinDetail("python3", "--version");
+    if (pythonVersion !== "failed") {
+      systemInfo["python version"] = pythonVersion
+        .toString()
+        .trim()
+        .split(" ")
+        .pop()
+        ?.trim();
+    }
+
+    // get python path
+    const pythonPathResult = await getBinDetail(
+      "python3",
+      '-c "import sys; print(sys.executable)"',
+    );
+    if (pythonPathResult !== "failed") {
+      systemInfo["python location"] = pythonPathResult.toString().trim();
+    }
+
+    // get ansible-creator version
+    const ansibleCreatorVersion = await getBinDetail(
+      "ansible-creator",
+      "--version",
+    );
+    if (ansibleCreatorVersion !== "failed") {
+      systemInfo["ansible-creator version"] = ansibleCreatorVersion
+        .toString()
+        .trim();
+    }
+
+    // get ansible-creator version
+    const ansibleDevEnvironmentVersion = await getBinDetail("ade", "--version");
+    if (ansibleDevEnvironmentVersion !== "failed") {
+      systemInfo["ansible-dev-environment version"] =
+        ansibleDevEnvironmentVersion.toString().trim();
+    }
+
+    // send the system details to the webview
+    webView.postMessage({ command: "systemDetails", arguments: systemInfo });
+  }
+}
diff --git a/src/webview/apps/contentCreator/welcomePageApp.ts b/src/webview/apps/welcomePage/welcomePageApp.ts
similarity index 100%
rename from src/webview/apps/contentCreator/welcomePageApp.ts
rename to src/webview/apps/welcomePage/welcomePageApp.ts
diff --git a/test/ui-test/allTestsSuite.ts b/test/ui-test/allTestsSuite.ts
index 89a3f4d95..5654055ac 100644
--- a/test/ui-test/allTestsSuite.ts
+++ b/test/ui-test/allTestsSuite.ts
@@ -3,12 +3,14 @@ import { lightspeedUILoginTest } from "./lightspeedAuthUiTest";
 import { lightspeedOneClickTrialUITest } from "./lightspeedOneClickTrialUITest";
 import { lightspeedUIAssetsTest } from "./lightspeedUiTest";
 import { terminalUITests } from "./terminalUiTest";
+import { welcomePageUITest } from "./welcomePageUITest";
 
 describe("VSCode Ansible - UI tests", function () {
   this.timeout(30000);
   extensionUIAssetsTest();
   lightspeedUIAssetsTest();
   terminalUITests();
+  welcomePageUITest();
 
   // Skip this on MacOS due to the functional limitation on menu support
   if (process.platform === "darwin") {
diff --git a/test/ui-test/lightspeedUiTest.ts b/test/ui-test/lightspeedUiTest.ts
index 88e55bf42..a7d617baa 100644
--- a/test/ui-test/lightspeedUiTest.ts
+++ b/test/ui-test/lightspeedUiTest.ts
@@ -194,7 +194,7 @@ export function lightspeedUIAssetsTest(): void {
     });
 
     it("Playbook generation webview works as expected (full path) - part 1", async function () {
-      // Open Ansible Content Creator by clicking the Getting started button on the side bar
+      // Open Ansible Development Tools by clicking the Getting started button on the side bar
       const view = (await new ActivityBar().getViewControl(
         "Ansible",
       )) as ViewControl;
@@ -212,7 +212,7 @@ export function lightspeedUIAssetsTest(): void {
       }
       await sleep(5000);
 
-      // Open Playbook Generation UI by clicking the create content button on Ansible Content Creator
+      // Open Playbook Generation UI by clicking the create content button on Ansible Development Tools
       const contentCreatorWebView = await new WebView();
       expect(
         contentCreatorWebView,
@@ -234,7 +234,7 @@ export function lightspeedUIAssetsTest(): void {
         await createContentButton.click();
       }
       await contentCreatorWebView.switchBack();
-      await new EditorView().closeEditor("Ansible content creator");
+      await new EditorView().closeEditor("Ansible Development Tools");
       await sleep(2000);
 
       // Start operations on Playbook Generation UI
diff --git a/test/ui-test/welcomePageUITest.ts b/test/ui-test/welcomePageUITest.ts
new file mode 100644
index 000000000..f1174662c
--- /dev/null
+++ b/test/ui-test/welcomePageUITest.ts
@@ -0,0 +1,92 @@
+import { config, expect } from "chai";
+import {
+  ActivityBar,
+  By,
+  SideBarView,
+  ViewControl,
+  ViewSection,
+  WebView,
+} from "vscode-extension-tester";
+import { sleep } from "./uiTestHelper";
+
+config.truncateThreshold = 0;
+export function welcomePageUITest(): void {
+  describe("Verify welcome page sidebar and title is displayed as expected", async () => {
+    let view: ViewControl;
+    let sideBar: SideBarView;
+    let adtSection: ViewSection;
+
+    before(async () => {
+      // Open Ansible Development Tools by clicking the Getting started button on the side bar
+      view = (await new ActivityBar().getViewControl("Ansible")) as ViewControl;
+      sideBar = await view.openView();
+      // to get the content part
+      adtSection = await sideBar
+        .getContent()
+        .getSection("Ansible Development Tools");
+    });
+
+    after(async function () {
+      if (view) {
+        await view.closeView();
+      }
+    });
+
+    it("check for title and get started button", async function () {
+      const title = await adtSection.getTitle();
+      const getStartedButton = await adtSection.findElement(
+        By.xpath(
+          "//a[contains(@class, 'monaco-button') and " +
+            ".//span/text()='Get started']",
+        ),
+      );
+
+      expect(title).not.to.be.undefined;
+      expect(title).to.equals("Ansible Development Tools");
+      expect(getStartedButton).not.to.be.undefined;
+    });
+
+    it("check for header and subtitle", async function () {
+      const getStartedButton = await adtSection.findElement(
+        By.xpath(
+          "//a[contains(@class, 'monaco-button') and " +
+            ".//span/text()='Get started']",
+        ),
+      );
+
+      expect(getStartedButton).not.to.be.undefined;
+
+      if (getStartedButton) {
+        await getStartedButton.click();
+      }
+      await sleep(3000);
+
+      const welcomePageWebView = await new WebView();
+      expect(welcomePageWebView, "welcomePageWebView should not be undefined")
+        .not.to.be.undefined;
+      await welcomePageWebView.switchToFrame(3000);
+      expect(
+        welcomePageWebView,
+        "welcomePageWebView should not be undefined after switching to its frame",
+      ).not.to.be.undefined;
+
+      const adtHeaderTitle = await welcomePageWebView.findWebElement(
+        By.className("title caption"),
+      );
+      expect(adtHeaderTitle).not.to.be.undefined;
+      expect(await adtHeaderTitle.getText()).to.equals(
+        "Ansible Development Tools",
+      );
+
+      const adtSubheader = await welcomePageWebView.findWebElement(
+        By.className("subtitle description"),
+      );
+      expect(adtSubheader).not.to.be.undefined;
+      expect(await adtSubheader.getText()).includes(
+        "Create, test and deploy Ansible content",
+      );
+
+      await welcomePageWebView.switchBack();
+    });
+  });
+}
diff --git a/webpack.config.ts b/webpack.config.ts
index bbfee58c2..af483ce7b 100644
--- a/webpack.config.ts
+++ b/webpack.config.ts
@@ -121,11 +121,11 @@ const webviewConfig = {
 const contentCreatorMenuWebviewConfig = {
   ...config,
   target: ["web", "es2020"],
-  entry: "./src/webview/apps/contentCreator/welcomePageApp.ts",
+  entry: "./src/webview/apps/welcomePage/welcomePageApp.ts",
   experiments: { outputModule: true },
   output: {
     path: path.resolve(__dirname, "out"),
-    filename: "./client/webview/apps/contentCreator/welcomePageApp.js",
+    filename: "./client/webview/apps/welcomePage/welcomePageApp.js",
     libraryTarget: "module",
     chunkFormat: "module",
   },