diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index 777c8410..bc8e4409 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -111,8 +111,20 @@ jobs: - build-macos if: ${{ success() && github.event.inputs.PERFORM_RELEASE == 'true' }} steps: - - name: '[Prep 3] Checkout' + - name: 'Checkout' uses: actions/checkout@v3 + + - name: 'Set tag value' + run: | + COMMIT_HASH=$(git rev-parse --verify HEAD) + CURRENT_TIME=$(date +%s%3N) + if [ -z ${{ github.event.pull_request.number }} ] + then + CURRENT_BRANCH=${GITHUB_REF#refs/heads/} + else + CURRENT_BRANCH=PR-${{ github.event.pull_request.number }} + fi + P_VERSION=$(cat package.json | grep -o '"version": *"[^"]*"' | sed 's/"version": "\(.*\)"/\1/') - name: '[Release 1] Release (if necessary)' if: ${{ success() && github.event.inputs.PERFORM_RELEASE == 'true' }} diff --git a/package-lock.json b/package-lock.json index acd813ed..5c50ff45 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "zowe-install-wizard", - "version": "1.0.0", + "version": "1.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "zowe-install-wizard", - "version": "1.0.0", + "version": "1.0.1", "license": "EPL 2.0", "dependencies": { "@emotion/react": "^11.10.6", @@ -12314,9 +12314,9 @@ } }, "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.17.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz", - "integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, "engines": { "node": ">=10.0.0" @@ -12488,9 +12488,9 @@ "dev": true }, "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "dev": true, "engines": { "node": ">=8.3.0" diff --git a/package.json b/package.json index 7c9d4c92..86e49446 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "author": "Zowe", "description": "Zowe Server Install Wizard", "productName": "zowe-install-wizard", - "version": "1.0.0", + "version": "1.0.1", "main": ".webpack/main", "scripts": { "start": "electron-forge start --enable-logging", diff --git a/playwright_test/Pages/apfAuth.page.ts b/playwright_test/Pages/apfAuth.page.ts index 92d3e5f6..ab389ffa 100644 --- a/playwright_test/Pages/apfAuth.page.ts +++ b/playwright_test/Pages/apfAuth.page.ts @@ -83,6 +83,9 @@ class ApfAuthPage{ this.dataset_prefix_value = page.getByLabel('Dataset Prefix') this.auth_load_lib_value = page.getByLabel('APF Authorized Load Library') this.auth_plugin_lib_value = page.getByLabel('Zowe ZIS Plugins Load Library') + + //this.select_SMPE = page.getByLabel('//button[contains(text(),"SMP/E")]') + this.select_SMPE = page.locator('span:has-text("SMP/E")'); } async returnTitleOfApfAuthPage(){ @@ -93,6 +96,13 @@ class ApfAuthPage{ async movetoApfAuthPage(){ await this.click_ApfAuth.click({timeout: 9000}) } + + async selectInstallationType(){ + await this.select_SMPE.waitFor({ state: 'visible', timeout: 9000 }); // Adjust timeout if needed + console.log('SMP/E span is visible.'); + await this.select_SMPE.click({timeout: 9000}) + } + async movetoInstallationPage(){ await this.licenseAgreement.click({timeout: 9000}) await this.acceptLicense.click({timeout: 9000}) diff --git a/playwright_test/Pages/connection.page.ts b/playwright_test/Pages/connection.page.ts index b1ff61a7..8e3085f3 100644 --- a/playwright_test/Pages/connection.page.ts +++ b/playwright_test/Pages/connection.page.ts @@ -24,19 +24,17 @@ class ConnectionPage{ this.resumeProgress = page.locator('//button[contains(text(),"Resume Progress")]') this.continueButton = page.locator('.MuiButton-containedPrimary.MuiButton-sizeMedium') this.greenCheckIconSelector = page.locator('.MuiContainer-root svg[data-testid="CheckCircleIcon"]') - - - } async fillConnectionDetails(host: string, port: string, username: string, password: string){ - await this.page.waitForTimeout(1000); - await this.host.fill(host) + console.log("Filling connection details..."); + await this.host.fill(host); await this.page.waitForTimeout(1000); await this.port.fill(port) await this.page.waitForTimeout(1000); await this.userName.fill(username) await this.page.waitForTimeout(1000); - await this.password.fill(password) + await this.password.fill(password); + console.log("Connection details filled."); } async getHostValue(){ @@ -60,8 +58,10 @@ class ConnectionPage{ } async SubmitValidateCredential(){ + console.log("Submitting credentials..."); await this.page.waitForTimeout(1000); - await this.validateCredential.click() + await this.validateCredential.click(); + console.log("Credentials submitted."); } async clickContinueButton() { @@ -75,12 +75,9 @@ class ConnectionPage{ async isContinueButtonVisible() { return await this.continueButton.isDisabled(); } - async clickContinueButton() { - return await this.continueButton.click(); - } async isGreenCheckIconVisible() { return await this.greenCheckIconSelector.isHidden(); } } - export default ConnectionPage; \ No newline at end of file +export default ConnectionPage; \ No newline at end of file diff --git a/playwright_test/Pages/installation.page.ts b/playwright_test/Pages/installation.page.ts index e4752476..ee8a1753 100644 --- a/playwright_test/Pages/installation.page.ts +++ b/playwright_test/Pages/installation.page.ts @@ -50,94 +50,86 @@ class InstallationPage{ return await this.pageTitle.textContent({ timeout: 2000 }); } - async enterPrefix(prefix: any){ + async enterPrefix(prefix: string): Promise{ await this.page.waitForTimeout(500) await this.prefix.fill(prefix); } - async getPrefixValue(){ - await this.page.waitForTimeout(500) - return await this.prefix.textContent(); + async getPrefixValue(): Promise { + return await this.prefix.inputValue(); } - async enterProcLib(proclib: any){ + async enterProcLib(proclib: string): Promise { await this.page.waitForTimeout(500) await this.procLib.fill(proclib); } - async getProclibValue(){ - await this.page.waitForTimeout(500) - return await this.procLib.textContent(); + + async getProclibValue(): Promise { + return await this.procLib.inputValue(); } - async enterParmLib(parmlib: any){ + async enterParmLib(parmlib: string): Promise{ await this.page.waitForTimeout(500) await this.parmLib.fill(parmlib); } - async getParmlibValue(){ - await this.page.waitForTimeout(500) - return await this.parmLib.textContent(); + async getParmlibValue(): Promise { + return await this.parmLib.inputValue(); } - async enterZis(zis: any){ + async enterZis(zis: string): Promise { await this.page.waitForTimeout(500) await this.zis.fill(zis); } - async enterJclLib(Jcllib: any){ + async enterJclLib(Jcllib: string): Promise { await this.page.waitForTimeout(500) await this.jclLib.fill(Jcllib); } - async enterLoadLib(loadlib: any){ + async enterLoadLib(loadlib: string): Promise{ await this.page.waitForTimeout(500) await this.loadLib.fill(loadlib); } - async enterAuthLoadLib(authloadlib: any){ - await this.page.waitForTimeout(500) + async enterAuthLoadLib(authloadlib: string): Promise { await this.authLoadLib.fill(authloadlib); + await this.page.waitForTimeout(5000) } - async getAuthLoadLibValue(){ - await this.page.waitForTimeout(500) - return await this.authLoadLib.textContent(); + async getAuthLoadLibValue(): Promise { + return await this.authLoadLib.inputValue(); } - async enterAuthPluginLib(authpluginlib: any){ - await this.page.waitForTimeout(500) + async enterAuthPluginLib(authpluginlib: string): Promise { await this.authPluginLib.fill(authpluginlib); + await this.page.waitForTimeout(5000) } - async getAuthPluginLibValue(){ - await this.page.waitForTimeout(500) - return await this.authPluginLib.textContent(); + async getAuthPluginLibValue(): Promise { + return await this.authPluginLib.inputValue(); } async clickInstallMvsDatasets(){ - await this.page.waitForTimeout(1000) - await this.installMVSDatasets.click(); + await this.installMVSDatasets.click(); + await this.waitForContinueButtonToBeEnabled(); } async clickViewEditYaml(){ - await this.page.waitForTimeout(500) await this.viewEditYaml.click(); } async clickViewSubmitJob(){ - await this.page.waitForTimeout(500) await this.viewSubmitJob.click(); } async clickViewJobOutput(){ - await this.page.waitForTimeout(500) await this.viewJobOutput.click(); await this.page.waitForTimeout(2000); } async clickSaveAndClose(){ - await this.page.waitForTimeout(500) await this.saveAndClose.click({timeout: 2000}); } @@ -157,14 +149,30 @@ class InstallationPage{ } async isContinueToNetworkSetupDisabled(){ - await this.page.waitForTimeout(500) return await this.continueToNetworkSetup.isDisabled() } async isContinueToNetworkSetupEnabled(){ - await this.page.waitForTimeout(500) return await this.continueToNetworkSetup.isEnabled() } + + async isSkipToNetworkSetupEnabled(){ + return await this.skipInstallation.isEnabled() + } + + private async waitForContinueButtonToBeEnabled(): Promise { + const timeout = 100000; + const interval = 500; + const endTime = Date.now() + timeout; + while (Date.now() < endTime) { + if (await this.isContinueToNetworkSetupEnabled()) { + return; + } + await this.page.waitForTimeout(interval); + } + + throw new Error('Continue button was not enabled within the timeout period'); + } async open_monacoEditor(){ await this.page.waitForTimeout(1000) @@ -177,5 +185,23 @@ class InstallationPage{ await this.page.waitForTimeout(500) await this.closeEditorButton.click(); } + + async clickInstallMvsDatasetsInvalid(){ + await this.installMVSDatasets.click(); + } + + async fillAllFields(datasetPrefix: string, parmLib: string, procLib: string, jclLib: string, loadLib: string, authLoadLib: string, authPluginLib: string){ + await this.enterPrefix(datasetPrefix); + await this.enterParmLib(parmLib); + await this.enterProcLib(procLib); + await this.enterJclLib(jclLib); + await this.enterLoadLib(loadLib); + await this.enterAuthLoadLib(authLoadLib); + await this.enterAuthPluginLib(authPluginLib); + await this.enterAuthLoadLib(authLoadLib); + await this.enterAuthPluginLib(authPluginLib); + await this.enterAuthLoadLib(authLoadLib); + await this.enterAuthPluginLib(authPluginLib); + } } export default InstallationPage; diff --git a/playwright_test/Pages/installationType.page.ts b/playwright_test/Pages/installationType.page.ts index b451ce2c..b7730c22 100644 --- a/playwright_test/Pages/installationType.page.ts +++ b/playwright_test/Pages/installationType.page.ts @@ -26,7 +26,7 @@ class InstallationTypePage{ this.uploadPax = page.locator("//span[text()='Upload Zowe PAX for offline install']/preceding-sibling::span/input") this.smpe = page.locator("//span[text()='SMP/E']/preceding-sibling::span/input") this.licenseAgreement = page.locator("//button[text()='License Agreement']") - this.saveAndClose = page.locator("//button[contains(text(),'Save & close')]") + this.saveAndClose = page.locator("//button[contains(text(),'Save & close')]") this.previousStep = page.locator("//button[contains(text(),'Previous step')]") this.continueToComponentInstallation = page.locator("//button[text()='Continue to Components Installation']") this.zoweLink = page.locator("//a[@href='zowe.org']") @@ -36,95 +36,107 @@ class InstallationTypePage{ this.validateLocation = page.locator("//button[text()= 'Validate location']") this.validateLocationGreenCheck = page.locator("//button[text()='Validate location']//following-sibling::*[@data-testid='CheckCircleIcon']") this.licenseAgreementGreenCheck = page.locator("//button[text()='License Agreement']//following-sibling::*[@data-testid='CheckCircleIcon']") + this.continueUpnax = page.locator("//button[contains(text(),'Continue to Unpax')]") + this.retrieveExampleZoweYaml = page.locator("//button[contains(text(),'Retrieve example-zowe.yaml')]") + this.continueCompInstallation = page.locator("//button[contains(text(),'Continue to Components Installation')]") + this.skipUnpaxButton = page.locator("//button[text()='Skip ']") } async getInstallationTypePageTitle(){ - await this.page.waitForTimeout(1000) return await this.pageTitle.textContent({ timeout: 2000 }); } async selectDownloadZowePax(){ - await this.page.waitForTimeout(1000) await this.downloadPax.click({timeout: 5000}) } async selectUploadZowePax(){ - await this.page.waitForTimeout(2000) await this.uploadPax.click({timeout: 5000}); } async selectSmpe(){ - await this.page.waitForTimeout(1000) await this.smpe.click({timeout: 5000}); } + + async continueToUnpax(){ + await this.continueUpnax.click({timeout: 5000}); + } + + async retrieveExampleYaml(){ + await this.retrieveExampleZoweYaml.click({timeout: 5000}); + } + + async continueComponentInstallation(){ + const timeout = 5000; + const interval = 500; + while (true) { + if (await this.continueCompInstallation.isEnabled()) { + await this.continueCompInstallation.click(); + return; + } + await this.page.waitForTimeout(interval); + } + await this.continueCompInstallation.click({timeout: timeout}); + } async clickZoweLink(){ - await this.page.waitForTimeout(1000) await this.zoweLink.click(); } async clickLicenseAgreement(){ - await this.page.waitForTimeout(1000) await this.licenseAgreement.click({timeout: 5000}); } async clickSaveAndClose(){ - await this.page.waitForTimeout(1000) await this.saveAndClose.click({timeout: 5000}); - await this.page.waitForTimeout(2000) } async clickPreviousStep(){ - await this.page.waitForTimeout(1000) await this.previousStep.click(); - await this.page.waitForTimeout(2000) } async clickContinueToInstallation(){ - await this.page.waitForTimeout(1000) await this.continueToComponentInstallation.click(); - await this.page.waitForTimeout(5000); } async isContinueToComponentInstallationDisabled(){ - await this.page.waitForTimeout(1000) return await this.continueToComponentInstallation.isDisabled() } async isContinueToComponentInstallationEnabled(){ - await this.page.waitForTimeout(1000) return await this.continueToComponentInstallation.isEnabled() } + + async isContinueUnpaxEnabled(){ + return await this.continueUpnax.isEnabled() + } async clickAgreeLicense(){ - await this.page.waitForTimeout(1000) await this.agreeLicense.click({timeout: 5000}); } async isLicenseAgreementGreenCheckVisible(){ - await this.page.waitForTimeout(1000) return await this.licenseAgreementGreenCheck.isVisible(); } async clickUploadPaxButton(){ - await this.page.waitForTimeout(1000) await this.uploadPaxButton.click({timeout: 5000}); } + + async skipUnpax(){ + await this.skipUnpaxButton.click({timeout: 5000}); + } async enterRuntimeDir(runtimeDir: any){ - await this.page.waitForTimeout(1000) await this.runtimeDir.clear({timeout: 5000}) await this.runtimeDir.fill(runtimeDir); } async clickValidateLocation(){ - await this.page.waitForTimeout(1000) await this.validateLocation.click({timeout: 5000}); - await this.page.waitForTimeout(2000) } async isValidateLocationGreenCheckVisible(){ - await this.page.waitForTimeout(1000) return await this.validateLocationGreenCheck.isVisible(); } @@ -136,15 +148,13 @@ class InstallationTypePage{ async uploadZowePaxAndNavigateToInstallationPage(uploadPaxPath: any){ this.selectUploadZowePax() - await this.page.waitForTimeout(2000) await this.uploadPaxButton.setInputFiles(uploadPaxPath) - await this.page.waitForTimeout(2000) } async smpeZowePaxAndNavigateToInstallationPage(runtimeDir: any){ this.selectSmpe() this.enterRuntimeDir(runtimeDir) this.clickValidateLocation() - } + } } export default InstallationTypePage; diff --git a/playwright_test/Pages/networking.page.ts b/playwright_test/Pages/networking.page.ts index eaff91ef..c654df8a 100644 --- a/playwright_test/Pages/networking.page.ts +++ b/playwright_test/Pages/networking.page.ts @@ -22,8 +22,6 @@ class NetworkingPage{ CONFPAGE_TITLE: Locator; continueToComponentInstallation: Locator; - - constructor(page: Page) { this.page = page; this.addDomainField = page.locator('//*[@id="zen-root-container"]/div[2]/div/div[4]/div/form/div/div[2]/p[1]/button'); @@ -37,7 +35,7 @@ class NetworkingPage{ this.metricService = page.locator('//strong[text()="metrics-service"]'); this.metricServiceEnbaled = page.locator('//*[@id="zen-root-container"]/div[2]/div/div[4]/div/form/div/div[2]/label[2]'); this.metricServiceDebug = page.locator('//*[@id="zen-root-container"]/div[2]/div/div[4]/div/form/div/div[2]/label[1]'); - this.metricServicePort = page.locator('//html/body/div/div[2]/div/div[4]/div/form/div/div[2]/div[4]/div/input'); + this.metricServicePort = page.locator('input[id=":rq:"]'); this.zss = page.getByLabel('zss'); this.zssTls = page.locator('//*[@id="zen-root-container"]/div[2]/div/div[4]/div/form/div/div[2]/label[3]'); this.zssPort = page.locator('//*[@id=":r1l:-label"]'); @@ -80,25 +78,26 @@ class NetworkingPage{ this.discoveryDebug = page.locator('//*[@id="zen-root-container"]/div[2]/div/div[4]/div/form/div/div[2]/label[22]'); this.discoveryEnabled = page.locator('//*[@id="zen-root-container"]/div[2]/div/div[4]/div/form/div/div[2]/label[23]'); this.discoveryPort = page.locator('//*[@id=":r25:-label"]'); - - this.metricService_debug_checkbox = page.locator('//*[@id="zen-root-container"]/div[2]/div/div[4]/div/form/div/div[2]/label[1]/span[1]/input'); + this.explorerUSS_debug_checkbox = page.locator('//*[@id="container-box-id"]/form/div/div[2]/div[4]/div/div[4]/div[1]/label/span[1]/input'); + this.app_server_debug = page.locator('//*[@id="container-box-id"]/form/div/div[2]/div[4]/div/div[11]/div[1]/label/span[1]/input'); + this.metricService_debug_checkbox = page.locator('//*[@id="container-box-id"]/form/div/div[2]/div[4]/div/div[1]/div[1]/label/span[1]/input'); this.metricService_enabled_checkbox = page.locator('//*[@id="zen-root-container"]/div[2]/div/div[4]/div/form/div/div[2]/label[2]/span[1]/input'); this.deleteDomainName = page.locator('//*[@id="zen-root-container"]/div[2]/div/div[4]/div/form/div/div[2]/div[2]/button'); this.readYaml = page.locator('div.view-lines'); this.previous_step_button = page.locator('//button[contains(text(),"Previous step")]'); - this.skip_button = page.locator('//button[contains(text(),"Skip")]'); this.editor_title_element = page.locator('//h2[text()="Editor"]'); this.NETWORKING_TITLE = page.locator(' //div[text()="Networking"]'); this.licenseAgreement = page.locator('//button[contains(text(), "License Agreement")]'); this.acceptLicense = page.locator('//html/body/div[2]/div[3]/div/div[2]/button[1]'); this.continueToComponentInstallation = page.locator('//button[contains(text(), "Continue to Components Installation")]'); - this.view_yaml = page.locator('//button[contains(text(),"View Yaml")]'); + this.view_yaml = page.locator('//button[contains(text(), "View/Edit Yaml")]'); this.viewAndSubmitJob = page.locator('//button[contains(text(), "Preview Job")]'); this.view_job_output = page.locator('//button[contains(text(), "Submit Job")]'); this.save_and_close = page.locator('//button[contains(text(),"Save & close")]'); this.previous_step = page.locator('//button[contains(text(),"Previous step")]'); - this.skip_button = page.locator('//button[contains(text(),"Skip")]'); - this.close_button = page.locator('//button[contains(text(), "Close")]'); + this.skip_button = page.locator('//button[contains(text(),"Skip ")]'); + //*[@id="zen-root-container"]/div[2]/div/div[5]/button[2] + this.close_button = page.locator("//button[text()='Close']"); this.APFAUTH_TITLE = page.locator('//div[text()="APF Authorize Load Libraries"]'); this.continue_ReviewSelector = page.locator('//button[contains(text(), "Continue to APF Auth Setup")]'); this.installationTitle = page.locator('//div[text()="Installation"]'); @@ -116,30 +115,24 @@ class NetworkingPage{ return networking_title; } - async fillExternalDomainPort(port:string){ + async fillExternalDomainPort(port: number){ await this.externalPort.fill(port, { timeout: 10000 }) } - async fillMetricServicePort(port:string){ - // Scroll down a bit - await this.page.evaluate(() => { - window.scrollBy(0, 200); - }); - // Add a wait after scrolling - await this.page.waitForTimeout(5000); - await this.metricServicePort.fill(port, { timeout: 10000 }) + async fillMetricServicePort(port: string){ + await this.metricServicePort.waitFor({ state: 'visible', timeout: 10000 }); + await this.metricServicePort.fill(port, { timeout: 10000 }); } - async get_metricServiceport_value(){ - const value = await this.metricServicePort.inputValue(); - return value; + async get_metricServiceport_value(): Promise { + return await this.metricServicePort.inputValue(); } async fillExternalDomainName(externalDomainName: string){ await this.domainName.fill(externalDomainName, { timeout: 10000 }); } - async fillexternal_domainvalues(externalDomainName:string, port: string){ + async fillexternal_domainvalues(externalDomainName:string, port: number){ await this.fillExternalDomainName(externalDomainName, { timeout: 10000 }); await this.fillExternalDomainPort(port, { timeout: 10000 }) } @@ -152,43 +145,62 @@ class NetworkingPage{ return value; } - async click_checkBox(n:string){ - const xpathLocator = `//*[@id="zen-root-container"]/div[2]/div/div[4]/div/form/div/div[2]/label[${n}]/span[1]/input`; - - const checkbox = await this.page.waitForSelector(xpathLocator, { state: 'visible' }); - - if (checkbox) { - const isChecked = await checkbox.evaluate((input) => input.checked); - console.log('Is checkbox checked:', isChecked); - - if (!isChecked) { - await checkbox.click(); - console.log('Checkbox clicked'); - } else { - console.log('Checkbox is already checked'); - } - } else { - console.log('Checkbox not found'); - } -} - - - async isCheckboxCheckedAndBlue(nthChild: string){ - const xpathLocator = `//*[@id="zen-root-container"]/div[2]/div/div[4]/div/form/div/div[2]/label[${nthChild}]/span[1]/input`; - - const checkbox = await this.page.waitForSelector(xpathLocator); - - if (checkbox) { - // Check if the checkbox is clicked - const isChecked = await checkbox.evaluate((input) => input.checked); - console.log('Is checkbox clicked:', isChecked); - return isChecked; - } else { - console.log('Checkbox not found'); + async click_checkBox(xpath: string): Promise { + //const html = await this.page.content(); // Get the HTML content + //console.log(html); + try { + const checkbox = await this.page.waitForSelector(xpath, { state: 'visible' }); + const isChecked = await checkbox.evaluate((input) => input.checked); + if (!isChecked) { + await checkbox.click(); + } + } catch (error) { + console.error(`Error checking checkbox with XPath "${xpath}":`, error); return false; - } + } + } + + + + async isCheckboxCheckedAndBlue(xpath: string): Promise{ + try{ + const checkbox = await this.page.waitForSelector(xpath); + if (checkbox) { + const isChecked = await checkbox.evaluate((input) => input.checked); + return isChecked; + } else { + return false; + } + } catch (error){ + console.log('Checkbox not found'); + return false; + + } + } + + async isMetricsServiceDebugChecked(): Promise { + return await this.isCheckboxCheckedAndBlue(this.metricService_debug_checkbox); + } + + async clickMetricsServiceDebug(): Promise { + await this.click_checkBox(this.metricService_debug_checkbox); + } + + async isExplorerUssDebugChecked(): Promise { + return await this.isCheckboxCheckedAndBlue(this.explorerUSS_debug_checkbox); } + async isAppServerDebugChecked(): Promise { + return await this.isCheckboxCheckedAndBlue(this.app_server_debug); + } + + async clickExplorerUssDebug(): Promise { + await this.click_checkBox(this.explorerUSS_debug_checkbox); + } + + async clickAppServerDebug(): Promise { + await this.click_checkBox(this.app_server_debug); + } async delete_DomainNameField(){ await this.deleteDomainName.click(); @@ -213,9 +225,12 @@ class NetworkingPage{ } async click_skipNetworking(){ - await this.skip_button.click({ timeout: 2000 }); - const apfAuth_title = await this.APFAUTH_TITLE.textContent(); - return apfAuth_title; + const isEnabled = await this.is_skipNetworkingButtonEnable(); + if (isEnabled) { + await this.skip_button.click({ timeout: 2000 }); + } else { + throw new Error('Skip button is not enabled and cannot be clicked.'); + } } async isPreviousButtonEnable(){ @@ -245,7 +260,6 @@ class NetworkingPage{ let allText = ''; while (true) { - // Extract text from all div.view-line elements const newText = await this.page.evaluate(() => { const viewLines = document.querySelectorAll('.view-lines .view-line'); let text = ''; @@ -254,36 +268,21 @@ class NetworkingPage{ }); return text; }); - - // Append the new text to the existing text allText += newText; - console.log(allText) - - // Scroll a little to load more content await this.page.evaluate(() => { const editor = document.querySelector('.monaco-scrollable-element.editor-scrollable.vs'); - editor.scrollTop += 100; // Adjust the scroll amount as needed + editor.scrollTop += 100; }); - - // Wait for a brief moment for new content to load - await this.page.waitForTimeout(1000); // Adjust timeout as needed - - // Get the current scroll height + await this.page.waitForTimeout(1000); const currentScrollHeight = await this.page.evaluate(() => { const editor = document.querySelector('.monaco-scrollable-element.editor-scrollable.vs'); return editor.scrollHeight; }); - - // If the scroll height hasn't changed since the last iteration, we've reached the end if (currentScrollHeight === previousScrollHeight) { break; } - - // Update the previous scroll height for the next iteration previousScrollHeight = currentScrollHeight; } - - console.log('All text:', allText); return allText; } diff --git a/playwright_test/Pages/planning.page.ts b/playwright_test/Pages/planning.page.ts index 63b8c87e..31757b92 100644 --- a/playwright_test/Pages/planning.page.ts +++ b/playwright_test/Pages/planning.page.ts @@ -45,11 +45,12 @@ class PlanningPage{ this.jobName = page.locator("//label[contains(text(),'Job Name')]//following-sibling::div/input") this.jobPrefix = page.locator("//label[contains(text(),'Job Prefix')]//following-sibling::div/input") this.cookieIdentifier = page.locator("//label[contains(text(),'Cookie Identifier')]//following-sibling::div/input") - this.javaLocation = page.locator("//label[contains(text(),'Java location')]//following-sibling::div/input") - this.nodeJsLocation = page.locator("//label[contains(text(),'Node.js location')]//following-sibling::div/input") + this.javaLocation = page.locator("//label[contains(text(),'Java Home Directory')]//following-sibling::div/input") + this.nodeJsLocation = page.locator("//label[contains(text(),'Node.js Home Directory')]//following-sibling::div/input") this.setZosmf = page.locator("//span[text()='Set z/OSMF Attributes (optional)']/preceding-sibling::span/input") this.zosmfHost = page.locator("//label[contains(text(),'z/OSMF Host')]//following-sibling::div/input") - this.zosmfPort = page.locator("//label[contains(text(),'z/OSMF Port')]//following-sibling::div/input") + this.zosmfPort = page.locator('//label[contains(text(), "z/OSMF Port")]/following-sibling::div/input[@id="zosmf-port"]') + //this.zosmfPort = page.locator('//input[@id="zosmf-port"]'); this.zosmfApplicationId = page.locator("//label[contains(text(),'z/OSMF Application Id')]//following-sibling::div/input") this.validateLocations = page.locator("//button[contains(text(), 'Validate locations')]") this.ValidateLocationsGreenCheck = page.locator("//button[text()='Validate locations']//following-sibling::*[@data-testid='CheckCircleIcon']") @@ -81,13 +82,17 @@ class PlanningPage{ } async clickSaveAndValidate(){ - await this.page.waitForTimeout(1000); await this.saveAndValidate.click({ timeout: 5000 }); } - async isSaveAndValidateGreenCheckVisible(){ - await this.page.waitForTimeout(1000); - return await this.saveAndValidateGreenCheck.isVisible({ timeout: 5000 }); + async isSaveAndValidateGreenCheckVisible(): Promise { + try { + await this.saveAndValidateGreenCheck.waitFor({ state: 'visible', timeout: 10000 }); + return true; + } catch (error) { + console.error('Error checking visibility:', error); + return false; + } } async getErrorMessage(){ @@ -97,7 +102,7 @@ class PlanningPage{ async enterRuntimeDir(runtimeDir: any){ await this.page.waitForTimeout(500); - await this.runtimeDir.clear({timeout: 2000}) + //await this.runtimeDir.clear({timeout: 2000}) await this.runtimeDir.fill(runtimeDir); } @@ -192,18 +197,23 @@ class PlanningPage{ } async clickValidateLocations(){ - await this.page.waitForTimeout(500); await this.validateLocations.click({timeout: 5000}); + await this.isContinueToInstallationEnabled() } - async isValidateLocationsGreenCheckVisible(){ - await this.page.waitForTimeout(500); - return await this.ValidateLocationsGreenCheck.isVisible(); + async isValidateLocationsGreenCheckVisible(): Promise { + try { + await this.ValidateLocationsGreenCheck.waitFor({ state: 'visible', timeout: 15000 }); + return true; + } catch (error) { + console.error('Error checking visibility:', error); + return false; + } } + async clickSaveAndClose(){ - await this.page.waitForTimeout(500); - await this.saveAndClose.click({timeout: 2000}); + await this.saveAndClose.click({timeout: 15000}); } async clickPreviousStep(){ @@ -212,8 +222,19 @@ class PlanningPage{ } async clickContinueToInstallation(){ - await this.page.waitForTimeout(500); - await this.continueInstallationOptions.click(); + const timeout = 30000; + const interval = 100; + const startTime = Date.now(); + const isButtonEnabled = async (): Promise => { + return await this.isContinueToInstallationEnabled(); + }; + while (!(await isButtonEnabled())) { + if (Date.now() - startTime > timeout) { + throw new Error('Timed out waiting for the button to be enabled.'); + } + await new Promise(resolve => setTimeout(resolve, interval)); + } + await this.continueInstallationOptions.click(); } async isContinueToInstallationDisabled(){ @@ -232,12 +253,13 @@ class PlanningPage{ } async clickSaveValidate(){ - await this.page.waitForTimeout(500); - await this.jobStatement.fill("//HELLOJOB JOB 'HELLO, WORLD!',CLASS=A,MSGCLASS=A\n//STEP01 EXEC PGM=IEFBR14\n//SYSPRINT DD SYSOUT=A\n//SYSIN DD DUMMY") + await this.jobStatement.fill("//ZWEJOB01 JOB IZUACCT,'SYSPROG',CLASS=A,\n// MSGLEVEL=(1,1),MSGCLASS=A") await this.saveAndValidate.click(); + await this.page.waitForTimeout(500); } + + async fillPlanningPageWithRequiredFields(runtimeDir: any, workspaceDir: any, extensionDir: any, logDir: any, profileIdentifier:any, jobPrefix:any,jobname:any, javaLocation:any,nodejsLocation:any,zOSMFHost:any,zOSMFPort:any,zOSMFAppID:any){ - await this.page.waitForTimeout(2000); await this.clickSaveValidate(); await this.enterRuntimeDir(runtimeDir); await this.enterWorkspaceDir(workspaceDir); @@ -248,8 +270,8 @@ class PlanningPage{ await this.enterJobPrefix(jobPrefix); await this.enterJavaLocation(javaLocation); await this.enterNodeJsLocation(nodejsLocation); - await this.enterZosmfHost(zOSMFHost); - await this.enterZosmfPort(zOSMFPort); + //await this.enterZosmfHost(zOSMFHost); + //await this.enterZosmfPort(zOSMFPort); await this.enterZosmfApplicationId(zOSMFAppID); await this.page.waitForTimeout(2000); } diff --git a/playwright_test/Pages/security.page.ts b/playwright_test/Pages/security.page.ts index 621fd5cb..89c4d20d 100644 --- a/playwright_test/Pages/security.page.ts +++ b/playwright_test/Pages/security.page.ts @@ -39,7 +39,6 @@ class SecurityPage{ this.uploadYaml_greenCheckXpath = page.locator('#card-download-progress-card svg.MuiSvgIcon-colorSuccess') this.init_security_greenCheckXpath = page.locator("#card-success-progress-card svg.MuiSvgIcon-colorSuccess") this.previous_step_button = page.locator('//button[contains(text(),"Previous step")]') - this.skip_button = page.locator('//button[contains(text(),"Skip")]') this.editor_title_element = page.locator('//h2[text()="Editor"]') this.APFAUTH_TITLE = page.locator('//div[text()="APF Authorize Load Libraries"]') this.licenseAgreement = page.locator('//button[contains(text(), "License Agreement")]') @@ -53,12 +52,13 @@ class SecurityPage{ this.view_job_output = page.locator('//button[contains(text(), "Submit Job")]') this.save_and_close = page.locator('//button[contains(text(),"Save & close")]') this.previous_step = page.locator('//button[contains(text(),"Previous step")]') - this.skip_button = page.locator('//button[contains(text(),"Skip")]') + this.skip_button = page.locator('//button[contains(text(),"Skip ")]') this.initSecurity = page.locator("//button[contains(text(), 'Initialize Security Config')]") this.close_button = page.locator('//button[contains(text(), "Close")]') this.certificateTab_title = page.locator('//div[text()="Certificates"]') + this.stc_title = page.locator('//div[text()="Stcs"]') this.securityTab_title = page.locator('//div[text()="Security"]') - this.continue_CertificateSelector = page.locator('//button[contains(text(), "Continue to Certificates Setup")]') + this.continue_CertificateSelector = page.locator('//button[contains(text(), "Continue to STC Setup")]') this.admin = page.getByLabel('Admin'); this.stc = page.getByLabel('Stc'); @@ -141,8 +141,6 @@ class SecurityPage{ async click_skipSecurity(){ await this.skip_button.click({ timeout: 2000 }); - const certificatePage_title = await this.certificateTab_title.textContent(); - return certificatePage_title; } async open_monacoEditor(){ @@ -190,10 +188,21 @@ class SecurityPage{ const sysProg_value = await this.sys_prog.textContent(); return sysProg_value; } - async returnTitleOfSecurityPage(){ + async returnTitleOfSecurityPage(){ const securityPage_title = await this.securityTab_title.textContent(); return securityPage_title; } + async returnTitleOfCertPage(){ + const certPage_title = await this.certificateTab_title.textContent(); + return certPage_title; + } + + async returnTitleOfstcPage(){ + const stcPage_title = await this.stc_title.textContent(); + return stcPage_title; + } + } - export default SecurityPage; \ No newline at end of file + +export default SecurityPage; \ No newline at end of file diff --git a/playwright_test/Tests/ApfAuth.spec.ts b/playwright_test/Tests/ApfAuth.spec.ts index 5c86a5c9..5d4b797d 100644 --- a/playwright_test/Tests/ApfAuth.spec.ts +++ b/playwright_test/Tests/ApfAuth.spec.ts @@ -4,6 +4,10 @@ import ApfAuthPage from '../Pages/ApfAuth.page'; import TitlePage from '../Pages/title.page'; import ConnectionPage from '../Pages/connection.page'; import PlanningPage from '../Pages/planning.page'; +import InstallationTypePage from '../Pages/installationType.page'; +import InstallationPage from '../Pages/installation.page.ts'; +import NetworkingPage from '../Pages/networking.page'; +import config from '../utils/config'; import { spawn } from 'child_process'; import path from 'path'; let page: Page; @@ -14,24 +18,7 @@ const APF_AUTH_TITLE ='APF Authorize Load Libraries' const NETWORKING_TITLE = 'Networking' const INSTALLATION_TITLE = 'Installation' const SECURITY_TITLE = 'Security' -const DATASET_PREFIX = 'IBMUSER.ZWEV1' -const AUTH_LOAD_LIB = 'IBMUSER.ZWEV1.ZWEAUTH' -const AUTH_PLUGIN_LIB = 'IBMUSER.ZWEV1.CUST.ZWESAPL' -const SSH_HOST = process.env.SSH_HOST; -const SSH_PASSWD = process.env.SSH_PASSWD; -const SSH_PORT = process.env.SSH_PORT; -const SSH_USER = process.env.SSH_USER; -const ZOWE_EXTENSION_DIR= process.env.ZOWE_EXTENSION_DIR; -const ZOWE_LOG_DIR=process.env.ZOWE_LOG_DIR; -const ZOWE_ROOT_DIR=process.env.ZOWE_ROOT_DIR; -const ZOWE_WORKSPACE_DIR=process.env.ZOWE_WORKSPACE_DIR; -const JOB_NAME= process.env.JOB_NAME; -const JOB_PREFIX=process.env.JOB_PREFIX; -const JAVA_HOME=process.env.JAVA_HOME; -const NODE_HOME=process.env.NODE_HOME; -const ZOSMF_HOST=process.env.ZOSMF_HOST; -const ZOSMF_PORT=process.env.ZOSMF_PORT; -const ZOSMF_APP_ID=process.env.ZOSMF_APP_ID; + test.beforeAll(async () => { try { @@ -42,64 +29,83 @@ test.beforeAll(async () => { } }); + test.describe('ApfAuthTab', () => { let connectionPage: ConnectionPage; let titlePage : TitlePage; let apfAuthPage : ApfAuthPage; let planningPage : PlanningPage; + let installationTypePage : InstallationTypePage; + let installationPage : InstallationPage; + let networkingPage : NetworkingPage; test.beforeEach(async ({ page }) => { test.setTimeout(900000); electronApp = await electron.launch({ args: ['.webpack/main/index.js'] }) - page= await electronApp.firstWindow() + page = await electronApp.firstWindow() connectionPage = new ConnectionPage(page); titlePage = new TitlePage(page); planningPage = new PlanningPage(page) apfAuthPage = new ApfAuthPage(page); + installationTypePage = new InstallationTypePage(page); + installationPage = new InstallationPage(page); + networkingPage = new NetworkingPage(page); titlePage.navigateToConnectionTab() - connectionPage.fillConnectionDetails(SSH_HOST,SSH_PORT,SSH_USER,SSH_PASSWD) - connectionPage.SubmitValidateCredential() - await page.waitForTimeout(5000); - connectionPage.clickContinueButton() - planningPage.clickSaveValidate() - await page.waitForTimeout(20000); - planningPage.fillPlanningPageWithRequiredFields(ZOWE_ROOT_DIR, ZOWE_WORKSPACE_DIR,ZOWE_EXTENSION_DIR,ZOWE_LOG_DIR,'1',JOB_NAME,JOB_PREFIX,JAVA_HOME,NODE_HOME,ZOSMF_HOST,ZOSMF_PORT,ZOSMF_APP_ID) - await page.waitForTimeout(20000); - planningPage.clickValidateLocations() - await page.waitForTimeout(30000); - planningPage.clickContinueToInstallation() - await page.waitForTimeout(5000); - apfAuthPage.movetoInstallationPage() - await page.waitForTimeout(5000); + await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); + await connectionPage.SubmitValidateCredential(); + await connectionPage.clickContinueButton(); + await planningPage.fillPlanningPageWithRequiredFields(config.ZOWE_ROOT_DIR, + config.ZOWE_WORKSPACE_DIR, + config.ZOWE_EXTENSION_DIR, + config.ZOWE_LOG_DIR, + '1', + config.JOB_NAME, + config.JOB_PREFIX, + config.JAVA_HOME, + config.NODE_HOME, + config.ZOSMF_HOST, + config.ZOSMF_PORT, + config.ZOSMF_APP_ID + ); + await planningPage.clickValidateLocations() + await planningPage.clickContinueToInstallation() + await installationTypePage.downloadZowePaxAndNavigateToInstallationPage() + await installationTypePage.continueToUnpax() + await installationTypePage.skipUnpax() + await installationPage.fillAllFields(config.DATASET_PREFIX, + config.PARM_LIB, + config.PROC_LIB, + config.JCL_LIB, + config.LOAD_LIB, + config.AUTH_LOAD_LIB, + config.AUTH_PLUGIN_LIB + ) + await installationPage.clickInstallMvsDatasets(); + await installationPage.clickContinueToNetworkSetup(); + await networkingPage.click_skipNetworking() + await page.waitForTimeout(1000); }) test.afterEach(async () => { await electronApp.close() }) test('Test Resume Progress', async ({ page }) => { - await page.waitForTimeout(8000); - apfAuthPage.fillApfDetails(DATASET_PREFIX,AUTH_LOAD_LIB,AUTH_PLUGIN_LIB) - await page.waitForTimeout(5000); + apfAuthPage.fillApfDetails(config.DATASET_PREFIX, config.AUTH_LOAD_LIB, config.AUTH_PLUGIN_LIB) apfAuthPage.click_saveAndClose() - await page.waitForTimeout(8000); connectionPage.click_resumeProgress() - await page.waitForTimeout(8000); const title = await apfAuthPage.returnTitleOfApfAuthPage(); - expect(title).toBe(APF_AUTH_TITLE); + expect(title).toBe(config.APF_AUTH_TITLE); const datatsetPrefixValue = await apfAuthPage.get_datasetPrefix_value(); const AuthLoadLib_Value = await apfAuthPage.get_authLoadLib_value(); const AuthPluginLib_Value = await apfAuthPage.get_authPluginLib_value(); - expect(datatsetPrefixValue).toBe(DATASET_PREFIX); - expect(AuthLoadLib_Value).toBe(AUTH_LOAD_LIB); - expect(AuthPluginLib_Value).toBe(AUTH_PLUGIN_LIB); + expect(datatsetPrefixValue).toBe(config.DATASET_PREFIX); + expect(AuthLoadLib_Value).toBe(config.AUTH_LOAD_LIB); + expect(AuthPluginLib_Value).toBe(config.AUTH_PLUGIN_LIB); }) test('Verify title', async ({ page }) => { - await page.waitForTimeout(5000); apfAuthPage.fillApfDetails(DATASET_PREFIX,AUTH_LOAD_LIB,AUTH_PLUGIN_LIB) - await page.waitForTimeout(5000); apfAuthPage.movetoApfAuthPage() - await page.waitForTimeout(5000); await expect(apfAuthPage.datasetPrefix).toBeTruthy() await expect(apfAuthPage.authLoadLib).toBeTruthy() await expect(apfAuthPage.authpluginLib).toBeTruthy() @@ -112,13 +118,9 @@ test.describe('ApfAuthTab', () => { }) test('test apfAuth with empty data', async ({ page }) => { - await page.waitForTimeout(5000); apfAuthPage.fillApfDetails('','','') - await page.waitForTimeout(5000); apfAuthPage.movetoApfAuthPage() - await page.waitForTimeout(5000); apfAuthPage.initializeApfauth() - await page.waitForTimeout(5000); const isWriteConfig_check_visible = await apfAuthPage.isWriteConfigGreenCheckVisible(); expect(isWriteConfig_check_visible).toBe(false); const isUploadConfig_check_visible = await apfAuthPage.isUploadConfig_check_visible(); @@ -127,13 +129,9 @@ test.describe('ApfAuthTab', () => { expect(isInitApf_check_visible).toBe(false); }) test('test apfAuth with valid data', async ({ page }) => { - await page.waitForTimeout(5000); apfAuthPage.fillApfDetails(DATASET_PREFIX,AUTH_LOAD_LIB,AUTH_PLUGIN_LIB) - await page.waitForTimeout(5000); apfAuthPage.movetoApfAuthPage() - await page.waitForTimeout(5000); apfAuthPage.initializeApfauth() - await page.waitForTimeout(5000); const isWriteConfig_check_visible = await apfAuthPage.isWriteConfigGreenCheckVisible(); expect(isWriteConfig_check_visible).toBe(true); const isUploadConfig_check_visible = await apfAuthPage.isUploadConfig_check_visible(); @@ -143,7 +141,6 @@ test.describe('ApfAuthTab', () => { }) test('click Previous step', async ({ page }) => { - await page.waitForTimeout(5000); apfAuthPage.movetoApfAuthPage() const title = await apfAuthPage.returnTitleOfPrevPage(); expect(title).toBe(NETWORKING_TITLE); @@ -153,31 +150,25 @@ test.describe('ApfAuthTab', () => { apfAuthPage.movetoApfAuthPage() const isSkipApfAuthEnable = await apfAuthPage.is_skipApfAuthButtonEnable(); expect(isSkipApfAuthEnable).toBe(true); - await page.waitForTimeout(2000); }) test('test previous button is enabled', async ({ page }) => { apfAuthPage.movetoApfAuthPage() const is_prevButtonEnable = await apfAuthPage.isPreviousButtonEnable(); expect(is_prevButtonEnable).toBe(true); - await page.waitForTimeout(2000); }) test('test continue button is disable', async ({ page }) => { apfAuthPage.movetoApfAuthPage() const is_ContinueButtonDisable = await apfAuthPage.isContinueButtonDisable(); expect(is_ContinueButtonDisable).toBe(true); - await page.waitForTimeout(2000); }) test('click view yaml button', async ({ page }) => { apfAuthPage.movetoApfAuthPage() - await page.waitForTimeout(5000); apfAuthPage.viewYaml() - await page.waitForTimeout(5000); await expect(apfAuthPage.editor_title_element).toBeTruthy(); apfAuthPage.closeButton() - await page.waitForTimeout(2000); }) test('test click skip APFAuth button', async ({ page }) => { @@ -189,44 +180,31 @@ test.describe('ApfAuthTab', () => { test('Test view and submit button', async ({ page }) => { apfAuthPage.movetoApfAuthPage() - await page.waitForTimeout(5000); apfAuthPage.click_viewAndSubmitJob() - await page.waitForTimeout(5000); await expect(apfAuthPage.editor_title_element).toBeTruthy() apfAuthPage.closeButton() - await page.waitForTimeout(2000); }) test('Test view job', async ({ page }) => { apfAuthPage.movetoApfAuthPage() - await page.waitForTimeout(5000); apfAuthPage.click_previewJob() - await page.waitForTimeout(5000); await expect(apfAuthPage.editor_title_element).toBeTruthy() apfAuthPage.closeButton() - await page.waitForTimeout(5000); }) test('Test save and close and Resume Progress', async ({ page }) => { - await page.waitForTimeout(5000); - apfAuthPage.fillApfDetails(DATASET_PREFIX,AUTH_LOAD_LIB,AUTH_PLUGIN_LIB) - await page.waitForTimeout(5000); + apfAuthPage.fillApfDetails(config.DATASET_PREFIX, config.AUTH_LOAD_LIB, config.AUTH_PLUGIN_LIB) apfAuthPage.movetoApfAuthPage() - await page.waitForTimeout(5000); apfAuthPage.click_saveAndClose() - await page.waitForTimeout(3000); titlePage.clickOnResumeProgress(); - await page.waitForTimeout(15000); const title = await securityPage.returnTitleOfSecurityPage(); expect(title).toBe(SECURITY_TITLE); const datatsetPrefixValue = await apfAuthPage.get_datasetPrefix_value(); const authPluginLibValue = await apfAuthPage.get_authPluginLib_value(); const authLoadLibValue = await apfAuthPage.get_authLoadLib_value(); - expect(datatsetPrefixValue).toBe(DATASET_PREFIX); - expect(authLoadLibValue).toBe(AUTH_LOAD_LIB); - expect(authPluginLibValue).toBe(AUTH_PLUGIN_LIB); + expect(datatsetPrefixValue).toBe(config.DATASET_PREFIX); + expect(authLoadLibValue).toBe(config.AUTH_LOAD_LIB); + expect(authPluginLibValue).toBe(config.AUTH_PLUGIN_LIB); }) - - }) \ No newline at end of file diff --git a/playwright_test/Tests/Connection.spec.ts b/playwright_test/Tests/Connection.spec.ts index 16284e19..5b5071c1 100644 --- a/playwright_test/Tests/Connection.spec.ts +++ b/playwright_test/Tests/Connection.spec.ts @@ -4,17 +4,16 @@ import TitlePage from '../Pages/title.page'; import path from 'path'; import { spawn } from 'child_process'; import { prepareEnvironment } from '../prepare.js'; +import config from '../utils/config'; +let page: Page; let electronApp: ElectronApplication -const SSH_HOST = process.env.SSH_HOST; -const SSH_PASSWD = process.env.SSH_PASSWD; -const SSH_PORT = process.env.SSH_PORT; -const SSH_USER = process.env.SSH_USER; const CONNECTION_PAGE_TITLE = 'Connection' +const INSTALLATION_TITLE = 'Installation' test.beforeAll(async () => { try { - await prepareEnvironment({ install: true, remove: false }); + await prepareEnvironment({ install: false, remove: false }); } catch (error) { console.error('Error during environment preparation:', error); process.exit(1); @@ -31,6 +30,7 @@ test.describe('ConnectionTab', () => { page= await electronApp.firstWindow() connectionPage = new ConnectionPage(page); titlePage = new TitlePage(page); + await titlePage.navigateToConnectionTab() }); test.afterEach(async () => { @@ -38,31 +38,23 @@ test.describe('ConnectionTab', () => { }); test('Test Save and close and Resume Progress', async ({ page }) => { - titlePage.navigateToConnectionTab() - connectionPage.fillConnectionDetails(SSH_HOST,SSH_PORT,SSH_USER,SSH_PASSWD) - await page.waitForTimeout(5000); - connectionPage.SubmitValidateCredential() - await page.waitForTimeout(2000); - connectionPage.click_saveAndClose() - await page.waitForTimeout(3000); - titlePage.clickOnResumeProgress(); - await page.waitForTimeout(5000); + await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); + await connectionPage.SubmitValidateCredential() + await connectionPage.click_saveAndClose() + await titlePage.clickOnResumeProgress(); const title = await connectionPage.getConnectionPageTitle(); expect(title).toBe(CONNECTION_PAGE_TITLE); const hostValue = await connectionPage.getHostValue(); - expect(hostValue).toBe(SSH_HOST); + expect(hostValue).toBe(config.SSH_HOST); const portValue = await connectionPage.getPortValue(); - expect(portValue).toBe(SSH_PORT); + expect(portValue).toBe(config.SSH_PORT); const userNameValue = await connectionPage.getUsernameValue(); - expect(userNameValue).toBe(SSH_USER); + expect(userNameValue).toBe(config.SSH_USER); }) test('test invalid credentials', async ({ page }) => { - titlePage.navigateToConnectionTab() - connectionPage.fillConnectionDetails(SSH_HOST,SSH_PORT,SSH_USER,SSH_PASSWD) - await page.waitForTimeout(5000); - connectionPage.SubmitValidateCredential() - await page.waitForTimeout(2000); + await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); + await connectionPage.SubmitValidateCredential() const isGreenIconHidden = await connectionPage.isGreenCheckIconVisible(); expect(isGreenIconHidden).toBe(true); const isContinueDisable = await connectionPage.isContinueButtonVisible(); @@ -70,11 +62,8 @@ test.describe('ConnectionTab', () => { }) test('test valid credentials', async ({ page }) => { - titlePage.navigateToConnectionTab() - connectionPage.fillConnectionDetails(SSH_HOST,SSH_PORT,SSH_USER,SSH_PASSWD) - await page.waitForTimeout(5000); - connectionPage.SubmitValidateCredential() - await page.waitForTimeout(8000); + await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); + await connectionPage.SubmitValidateCredential() const isGreenIconHidden = await connectionPage.isGreenCheckIconVisible(); expect(isGreenIconHidden).toBe(false); const isContinueDisable = await connectionPage.isContinueButtonVisible(); @@ -86,13 +75,10 @@ test.describe('ConnectionTab', () => { await expect(connectionPage.password).toBeTruthy() await expect(connectionPage.port).toBeTruthy() await expect(connectionPage.host).toBeTruthy() - await page.waitForTimeout(2000); }) test('test continue disable', async ({ page }) => { - titlePage.navigateToConnectionTab() const isContinueButtonDisable = await connectionPage.isContinueButtonVisible(); expect(isContinueButtonDisable).toBe(true); - await page.waitForTimeout(2000); }) }) \ No newline at end of file diff --git a/playwright_test/Tests/Installation.spec.ts b/playwright_test/Tests/Installation.spec.ts index 38d84ee5..5fa352eb 100644 --- a/playwright_test/Tests/Installation.spec.ts +++ b/playwright_test/Tests/Installation.spec.ts @@ -5,34 +5,14 @@ import PlanningPage from '../Pages/planning.page.ts'; import InstallationTypePage from '../Pages/installationType.page.ts'; import InstallationPage from '../Pages/installation.page.ts'; import NetworkingPage from '../Pages/networking.page.ts'; +import config from '../utils/config'; let electronApp: ElectronApplication const NETWORKING_PAGE_TITLE = 'Networking' -const INSTALLATION_TYPE_TITLE = 'Installation Type'; -const RUNTIME_DIR = process.env.ZOWE_ROOT_DIR; -const SSH_HOST = process.env.SSH_HOST; -const SSH_PASSWD = process.env.SSH_PASSWD; -const SSH_PORT = process.env.SSH_PORT; -const SSH_USER = process.env.SSH_USER; -const ZOWE_EXTENSION_DIR= process.env.ZOWE_EXTENSION_DIR; -const ZOWE_LOG_DIR=process.env.ZOWE_LOG_DIR; -const ZOWE_WORKSPACE_DIR=process.env.ZOWE_WORKSPACE_DIR; -const JOB_NAME= process.env.JOB_NAME; -const JOB_PREFIX=process.env.JOB_PREFIX; -const JAVA_HOME=process.env.JAVA_HOME; -const NODE_HOME=process.env.NODE_HOME; -const ZOSMF_HOST=process.env.ZOSMF_HOST; -const ZOSMF_PORT=process.env.ZOSMF_PORT; -const ZOSMF_APP_ID=process.env.ZOSMF_APP_ID; -const DATASET_PREFIX= process.env.DATASET_PREFIX; -const PROC_LIB = process.env.PROC_LIB; -const PARM_LIB = process.env.PARM_LIB; -const ZIS = process.env.SECURITY_STC_ZIS; -const JCL_LIB = process.env.JCL_LIB; -const LOAD_LIB = process.env.LOAD_LIB; -const AUTH_LOAD_LIB = process.env.AUTH_LOAD_LIB; -const AUTH_PLUGIN_LIB = process.env.AUTH_PLUGIN_LIB; -const UPLOAD_PAX_PATH= process.env.ZOWE_ROOT_DIR +const INSTALLATION_TYPE_TITLE = 'Installation'; +const DOWNLOAD_ZOWE_TITLE = 'Download Zowe Pax'; + + test.describe('InstallationTab', () => { let connectionPage: ConnectionPage; @@ -46,27 +26,36 @@ test.describe('InstallationTab', () => { test.beforeEach(async ({ page }) => { test.setTimeout(900000); electronApp = await electron.launch({ args: ['.webpack/main/index.js'] }) - page= await electronApp.firstWindow() + page = await electronApp.firstWindow() connectionPage = new ConnectionPage(page); titlePage = new TitlePage(page); planningPage = new PlanningPage(page); installationTypePage = new InstallationTypePage(page); installationPage = new InstallationPage(page); networkingPage = new NetworkingPage(page); + titlePage.navigateToConnectionTab() - connectionPage.fillConnectionDetails(SSH_HOST,SSH_PORT,SSH_USER,SSH_PASSWD) - connectionPage.SubmitValidateCredential() - await page.waitForTimeout(5000); - connectionPage.clickContinueButton() - await page.waitForTimeout(2000); - planningPage.clickSaveValidate() - await page.waitForTimeout(20000); - planningPage.fillPlanningPageWithRequiredFields(RUNTIME_DIR, ZOWE_WORKSPACE_DIR,ZOWE_EXTENSION_DIR,ZOWE_LOG_DIR,'1',JOB_NAME,JOB_PREFIX,JAVA_HOME,NODE_HOME,ZOSMF_HOST,ZOSMF_PORT,ZOSMF_APP_ID) - await page.waitForTimeout(20000); - planningPage.clickValidateLocations() - await page.waitForTimeout(20000); - planningPage.clickContinueToInstallation() - await page.waitForTimeout(5000); + await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); + await connectionPage.SubmitValidateCredential(); + await connectionPage.clickContinueButton(); + await planningPage.fillPlanningPageWithRequiredFields(config.ZOWE_ROOT_DIR, + config.ZOWE_WORKSPACE_DIR, + config.ZOWE_EXTENSION_DIR, + config.ZOWE_LOG_DIR, + '1', + config.JOB_NAME, + config.JOB_PREFIX, + config.JAVA_HOME, + config.NODE_HOME, + config.ZOSMF_HOST, + config.ZOSMF_PORT, + config.ZOSMF_APP_ID + ); + await planningPage.clickValidateLocations() + await planningPage.clickContinueToInstallation() + await installationTypePage.downloadZowePaxAndNavigateToInstallationPage() + await installationTypePage.continueToUnpax() + await installationTypePage.skipUnpax() }) test.afterEach(async () => { @@ -74,10 +63,6 @@ test.describe('InstallationTab', () => { }) test('Test all required fields on Installation page', async ({ page }) => { - await page.waitForTimeout(5000) - installationTypePage.downloadZowePaxAndNavigateToInstallationPage() - installationTypePage.clickContinueToInstallation() - await page.waitForTimeout(5000); expect(installationPage.prefix).toBeTruthy() expect(installationPage.procLib).toBeTruthy() expect(installationPage.parmLib).toBeTruthy() @@ -93,182 +78,91 @@ test.describe('InstallationTab', () => { expect(installationPage.saveAndClose).toBeTruthy() expect(installationPage.previousStep).toBeTruthy() expect(installationPage.skipInstallation).toBeTruthy() - expect(installationPage.continueToNetworkSetup).toBeTruthy() - const is_Continue_Button_disable = await installationPage.isContinueToNetworkSetupDisabled(); + expect(installationPage.clickContinueToNetworkSetup).toBeTruthy() + const is_Continue_Button_disable = await installationPage.isContinueToNetworkSetupEnabled(); expect(is_Continue_Button_disable).toBe(true); }) test('Test Installation with Valid Data with Download Pax', async ({ page }) => { - await page.waitForTimeout(5000); - installationTypePage.downloadZowePaxAndNavigateToInstallationPage() - installationTypePage.clickContinueToInstallation() - await page.waitForTimeout(5000); - installationPage.enterPrefix(DATASET_PREFIX) - installationPage.enterProcLib(PROC_LIB) - installationPage.enterParmLib(PARM_LIB) - installationPage.enterZis(ZIS) - installationPage.enterJclLib(JCL_LIB) - installationPage.enterLoadLib(LOAD_LIB) - installationPage.enterAuthLoadLib(AUTH_LOAD_LIB) - installationPage.enterAuthPluginLib(AUTH_PLUGIN_LIB) - installationPage.clickInstallMvsDatasets(); - await page.waitForTimeout(1800000); - const is_Continue_Button_enable = await installationPage.isContinueToNetworkSetupEnabled(); - expect(is_Continue_Button_enable).toBe(true); - installationPage.clickContinueToNetworkSetup(); - await page.waitForTimeout(2000); - const networkSetup_title = await networkingPage.returnTitleOfNetworkingPage() - expect (networkSetup_title).toBe(NETWORKING_PAGE_TITLE); - }) - - test('Test Installation with Valid Data with Upload Pax', async ({ page }) => { - await page.waitForTimeout(5000); - installationTypePage.uploadZowePaxAndNavigateToInstallationPage(UPLOAD_PAX_PATH) - installationTypePage.clickContinueToInstallation() - await page.waitForTimeout(5000); - installationPage.enterPrefix(DATASET_PREFIX) - installationPage.enterProcLib(PROC_LIB) - installationPage.enterParmLib(PARM_LIB) - installationPage.enterZis(ZIS) - installationPage.enterJclLib(JCL_LIB) - installationPage.enterLoadLib(LOAD_LIB) - installationPage.enterAuthLoadLib(AUTH_LOAD_LIB) - installationPage.enterAuthPluginLib(AUTH_PLUGIN_LIB) - installationPage.clickInstallMvsDatasets(); - await page.waitForTimeout(1800000); - const is_Continue_Button_enable = await installationPage.isContinueToNetworkSetupEnabled(); - expect(is_Continue_Button_enable).toBe(true); - installationPage.clickContinueToNetworkSetup(); - await page.waitForTimeout(2000); - const networkSetup_title = await networkingPage.returnTitleOfNetworkingPage() - expect (networkSetup_title).toBe(NETWORKING_PAGE_TITLE); - }) - - test('Test Installation with Valid Data with SMPE', async ({ page }) => { - await page.waitForTimeout(5000); - installationTypePage.smpeZowePaxAndNavigateToInstallationPage(RUNTIME_DIR) - installationTypePage.clickContinueToInstallation() - await page.waitForTimeout(5000); - installationPage.enterPrefix(DATASET_PREFIX) - installationPage.enterProcLib(PROC_LIB) - installationPage.enterParmLib(PARM_LIB) - installationPage.enterZis(ZIS) - installationPage.enterJclLib(JCL_LIB) - installationPage.enterLoadLib(LOAD_LIB) - installationPage.enterAuthLoadLib(AUTH_LOAD_LIB) - installationPage.enterAuthPluginLib(AUTH_PLUGIN_LIB) - installationPage.clickInstallMvsDatasets(); - await page.waitForTimeout(1800000); + await installationPage.fillAllFields(config.DATASET_PREFIX, + config.PARM_LIB, + config.PROC_LIB, + config.JCL_LIB, + config.LOAD_LIB, + config.AUTH_LOAD_LIB, + config.AUTH_PLUGIN_LIB + ) + await installationPage.clickInstallMvsDatasets(); const is_Continue_Button_enable = await installationPage.isContinueToNetworkSetupEnabled(); expect(is_Continue_Button_enable).toBe(true); - installationPage.clickContinueToNetworkSetup(); - await page.waitForTimeout(2000); - const networkSetup_title = await networkingPage.returnTitleOfNetworkingPage() - expect (networkSetup_title).toBe(NETWORKING_PAGE_TITLE); + await installationPage.clickContinueToNetworkSetup(); + const networkconfig_title = await networkingPage.returnTitleOfNetworkingPage() + expect (networkconfig_title).toBe(NETWORKING_PAGE_TITLE); }) test('Test Installation with the Invalid Data', async ({ page }) => { - await page.waitForTimeout(5000); - installationTypePage.downloadZowePaxAndNavigateToInstallationPage() - installationTypePage.clickContinueToInstallation() - await page.waitForTimeout(5000); - installationPage.enterPrefix('DSPREFID') - installationPage.enterProcLib('') - installationPage.enterParmLib(9999) - installationPage.enterZis(ZIS) - installationPage.enterJclLib('BLANK') - installationPage.enterLoadLib('') - installationPage.enterAuthLoadLib('AuthLoad') - installationPage.enterAuthPluginLib('') - installationPage.clickInstallMvsDatasets(); - await page.waitForTimeout(1800000); + await installationPage.enterPrefix('DSPREFID') + await installationPage.enterProcLib('') + await installationPage.enterParmLib('test') + await installationPage.enterJclLib('BLANK') + await installationPage.enterLoadLib('') + await installationPage.enterAuthLoadLib('AuthLoad') + await installationPage.enterAuthPluginLib('') + await installationPage.clickInstallMvsDatasetsInvalid(); + await installationPage.clickCloseEditor(); const is_Continue_Button_enable = await installationPage.isContinueToNetworkSetupEnabled(); expect(is_Continue_Button_enable).toBe(false); }) test('Test Previous step', async ({ page }) => { - await page.waitForTimeout(5000); - installationTypePage.downloadZowePaxAndNavigateToInstallationPage() - installationTypePage.clickContinueToInstallation() - await page.waitForTimeout(5000); - installationPage.clickPreviousStep(); - await page.waitForTimeout(2000); + await installationPage.clickPreviousStep(); const title = await installationTypePage.getInstallationTypePageTitle(); - expect(title).toBe(INSTALLATION_TYPE_TITLE); + expect(title).toBe(DOWNLOAD_ZOWE_TITLE); }) test('Test Skip Installation Button', async ({ page }) => { - await page.waitForTimeout(5000); - installationTypePage.downloadZowePaxAndNavigateToInstallationPage() - installationTypePage.clickContinueToInstallation() - await page.waitForTimeout(5000); - const is_Continue_Button_disable = await installationPage.isContinueToNetworkSetupDisabled(); - expect(is_Continue_Button_disable).toBe(true); - installationPage.clickSkipInstallation() - await page.waitForTimeout(2000); - const title = await networkingPage.returnTitleOfNetworkingPage(); - expect(title).toBe(NETWORKING_PAGE_TITLE); + const is_Continue_Button_disable = await installationPage.isContinueToNetworkSetupEnabled(); + expect(is_Continue_Button_disable).toBe(false); + const is_Skip_Button_disable = await installationPage.isSkipToNetworkSetupEnabled(); + expect(is_Skip_Button_disable).toBe(false); + const title = await installationTypePage.getInstallationTypePageTitle(); + expect(title).toBe(INSTALLATION_TYPE_TITLE); }) test('Test View Yaml Button', async ({ page }) => { - await page.waitForTimeout(5000); - installationTypePage.downloadZowePaxAndNavigateToInstallationPage() - installationTypePage.clickContinueToInstallation() - await page.waitForTimeout(5000); - installationPage.clickViewEditYaml() - await page.waitForTimeout(5000); - expect(installationPage.editorTitleElement).toBeTruthy(); - installationPage.clickCloseEditor() - await page.waitForTimeout(2000); - }) - - test('Test View and Submit button', async ({ page }) => { - await page.waitForTimeout(5000); - installationTypePage.downloadZowePaxAndNavigateToInstallationPage() - installationTypePage.clickContinueToInstallation() - await page.waitForTimeout(5000); - installationPage.clickViewSubmitJob() - await page.waitForTimeout(5000); + await installationPage.clickViewEditYaml() expect(installationPage.editorTitleElement).toBeTruthy(); - installationPage.clickCloseEditor() - await page.waitForTimeout(2000); + await installationPage.clickCloseEditor() }) test('Test View Job Output', async ({ page }) => { - await page.waitForTimeout(5000); - installationTypePage.downloadZowePaxAndNavigateToInstallationPage() - installationTypePage.clickContinueToInstallation() - await page.waitForTimeout(5000); - installationPage.clickViewJobOutput() - await page.waitForTimeout(5000); + await installationPage.clickViewJobOutput() expect(installationPage.editorTitleElement).toBeTruthy(); - installationPage.clickCloseEditor() - await page.waitForTimeout(2000); + await installationPage.clickCloseEditor() }) test('Test Save and Close and Resume Progress', async ({page}) => { - await page.waitForTimeout(5000); - installationTypePage.downloadZowePaxAndNavigateToInstallationPage() - installationTypePage.clickContinueToInstallation() - await page.waitForTimeout(5000); - installationPage.enterPrefix(DATASET_PREFIX) - installationPage.enterProcLib(PROC_LIB) - installationPage.enterParmLib(PARM_LIB) - installationPage.enterAuthLoadLib(AUTH_LOAD_LIB) - installationPage.enterAuthPluginLib(AUTH_PLUGIN_LIB) - installationPage.clickSaveAndClose(); - await page.waitForTimeout(3000); - titlePage.clickOnResumeProgress(); - await page.waitForTimeout(5000); + await installationPage.fillAllFields(config.DATASET_PREFIX, + config.PARM_LIB, + config.PROC_LIB, + config.JCL_LIB, + config.LOAD_LIB, + config.AUTH_LOAD_LIB, + config.AUTH_PLUGIN_LIB + ) + await installationPage.clickSaveAndClose(); + await titlePage.clickOnResumeProgress(); + await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); + await connectionPage.SubmitValidateCredential(); const prefix_value = await installationPage.getPrefixValue(); const procLib_value = await installationPage.getProclibValue(); const parmLib_value = await installationPage.getParmlibValue(); const authLoadLib_value = await installationPage.getAuthLoadLibValue(); const authPluginLib_value = await installationPage.getAuthPluginLibValue(); - expect(prefix_value).toBe(DATASET_PREFIX); - expect(parmLib_value).toBe(PARM_LIB); - expect(procLib_value).toBe(PROC_LIB); - expect(authLoadLib_value).toBe(AUTH_LOAD_LIB); - expect(authPluginLib_value).toBe(AUTH_PLUGIN_LIB); + expect(prefix_value).toBe(config.DATASET_PREFIX); + expect(parmLib_value).toBe(config.PARM_LIB); + expect(procLib_value).toBe(config.PROC_LIB); + expect(authLoadLib_value).toBe(config.AUTH_LOAD_LIB); + expect(authPluginLib_value).toBe(config.AUTH_PLUGIN_LIB); }) }) \ No newline at end of file diff --git a/playwright_test/Tests/InstallationType.spec.ts b/playwright_test/Tests/InstallationType.spec.ts index 76cc395f..80a67e1e 100644 --- a/playwright_test/Tests/InstallationType.spec.ts +++ b/playwright_test/Tests/InstallationType.spec.ts @@ -4,26 +4,13 @@ import ConnectionPage from '../Pages/connection.page.ts'; import PlanningPage from '../Pages/planning.page.ts'; import InstallationTypePage from '../Pages/installationType.page.ts'; import InstallationPage from '../Pages/installation.page.ts'; +import config from '../utils/config'; let electronApp: ElectronApplication const PLANNING_TITLE = 'Before you start'; const INSTALLATION_PAGE_TITLE = 'Installation'; -const RUNTIME_DIR = process.env.ZOWE_ROOT_DIR; -const SSH_HOST = process.env.SSH_HOST; -const SSH_PASSWD = process.env.SSH_PASSWD; -const SSH_PORT = process.env.SSH_PORT; -const SSH_USER = process.env.SSH_USER; -const ZOWE_EXTENSION_DIR= process.env.ZOWE_EXTENSION_DIR; -const ZOWE_LOG_DIR=process.env.ZOWE_LOG_DIR; -const ZOWE_WORKSPACE_DIR=process.env.ZOWE_WORKSPACE_DIR; -const JOB_NAME= process.env.JOB_NAME; -const JOB_PREFIX=process.env.JOB_PREFIX; -const JAVA_HOME=process.env.JAVA_HOME; -const NODE_HOME=process.env.NODE_HOME; -const ZOSMF_HOST=process.env.ZOSMF_HOST; -const ZOSMF_PORT=process.env.ZOSMF_PORT; -const ZOSMF_APP_ID=process.env.ZOSMF_APP_ID; -const UPLOAD_PAX_PATH= process.env.ZOWE_ROOT_DIR +const DOWNLOAD_ZOWE_PAX = 'Download Zowe Pax'; + test.describe('InstallationTypeTab', () => { let connectionPage: ConnectionPage; @@ -35,26 +22,31 @@ test.describe('InstallationTypeTab', () => { test.beforeEach(async ({ page }) => { test.setTimeout(900000); electronApp = await electron.launch({ args: ['.webpack/main/index.js'] }) - page= await electronApp.firstWindow() + page = await electronApp.firstWindow() connectionPage = new ConnectionPage(page); titlePage = new TitlePage(page); planningPage = new PlanningPage(page); installationTypePage = new InstallationTypePage(page); installationPage = new InstallationPage(page); titlePage.navigateToConnectionTab() - connectionPage.fillConnectionDetails(SSH_HOST,SSH_PORT,SSH_USER,SSH_PASSWD) - await page.waitForTimeout(5000); - connectionPage.SubmitValidateCredential() - await page.waitForTimeout(2000); - connectionPage.clickContinueButton() - planningPage.clickSaveValidate() - await page.waitForTimeout(20000); - planningPage.fillPlanningPageWithRequiredFields(RUNTIME_DIR, ZOWE_WORKSPACE_DIR,ZOWE_EXTENSION_DIR,ZOWE_LOG_DIR,'1',JOB_NAME,JOB_PREFIX,JAVA_HOME,NODE_HOME,ZOSMF_HOST,ZOSMF_PORT,ZOSMF_APP_ID) - await page.waitForTimeout(20000); - planningPage.clickValidateLocations() - await page.waitForTimeout(20000); - planningPage.clickContinueToInstallation() - await page.waitForTimeout(5000); + await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); + await connectionPage.SubmitValidateCredential(); + await connectionPage.clickContinueButton(); + await planningPage.fillPlanningPageWithRequiredFields(config.ZOWE_ROOT_DIR, + config.ZOWE_WORKSPACE_DIR, + config.ZOWE_EXTENSION_DIR, + config.ZOWE_LOG_DIR, + '1', + config.JOB_NAME, + config.JOB_PREFIX, + config.JAVA_HOME, + config.NODE_HOME, + config.ZOSMF_HOST, + config.ZOSMF_PORT, + config.ZOSMF_APP_ID + ); + await planningPage.clickValidateLocations() + await planningPage.clickContinueToInstallation() }) test.afterEach(async () => { @@ -62,7 +54,6 @@ test.describe('InstallationTypeTab', () => { }) test('Test all required fields on Installation Type page', async ({ page }) => { - await page.waitForTimeout(5000) expect(installationTypePage.downloadPax).toBeTruthy() expect(installationTypePage.uploadPax).toBeTruthy() expect(installationTypePage.smpe).toBeTruthy() @@ -70,97 +61,62 @@ test.describe('InstallationTypeTab', () => { expect(installationTypePage.saveAndClose).toBeTruthy() expect(installationTypePage.previousStep).toBeTruthy() expect(installationTypePage.continueToComponentInstallation).toBeTruthy() - const is_Continue_Button_disable = await installationTypePage.isContinueToComponentInstallationDisabled(); - expect(is_Continue_Button_disable).toBe(true); + const is_continue_button_enabled = await installationTypePage.isContinueUnpaxEnabled(); + expect(is_continue_button_enabled).toBe(false); }) test('Test Downlad Zowe Pax', async ({ page }) => { - await page.waitForTimeout(5000) - installationTypePage.selectDownloadZowePax() - installationTypePage.clickLicenseAgreement() - installationTypePage.clickAgreeLicense() + await installationTypePage.selectDownloadZowePax() + await installationTypePage.clickLicenseAgreement() + await installationTypePage.clickAgreeLicense() const is_GreenCheck_Visible = await installationTypePage.isLicenseAgreementGreenCheckVisible(); expect(is_GreenCheck_Visible).toBe(true); - const Is_Continue_Button_Enable = await installationTypePage.isContinueToComponentInstallationEnabled(); - expect(Is_Continue_Button_Enable).toBe(true); + const is_continue_button_enabled = await installationTypePage.isContinueUnpaxEnabled(); + expect(is_continue_button_enabled).toBe(true); }) + /* Need to figure out new logic test('Test Upload Zowe Pax', async ({ page }) => { - await page.waitForTimeout(5000) - installationTypePage.uploadZowePaxAndNavigateToInstallationPage(UPLOAD_PAX_PATH) - const Is_Continue_Button_Enable = await installationTypePage.isContinueToComponentInstallationEnabled(); + await installationTypePage.uploadZowePaxAndNavigateToInstallationPage(UPLOAD_PAX_PATH) + const Is_Continue_Button_Enable = await installationTypePage.isContinueUnpaxEnabled(); expect(Is_Continue_Button_Enable).toBe(true); - }) + })*/ - test('Test SMPE with Valid Path', async ({ page }) => { - await page.waitForTimeout(5000) - installationTypePage.selectSmpe() - installationTypePage.enterRuntimeDir(RUNTIME_DIR) - installationTypePage.clickValidateLocation() - await page.waitForTimeout(5000) - const is_GreenCheck_Visible = await installationTypePage.isValidateLocationGreenCheckVisible(); - expect(is_GreenCheck_Visible).toBe(true); - const Is_Continue_Button_Enable = await installationTypePage.isContinueToComponentInstallationEnabled(); + test('Test SMPE ', async ({ page }) => { + await installationTypePage.selectSmpe() + const Is_Continue_Button_Enable = await installationTypePage.isContinueUnpaxEnabled(); expect(Is_Continue_Button_Enable).toBe(true); }) - test('Test SMPE with Invalid Path', async ({ page }) => { - await page.waitForTimeout(5000) - installationTypePage.selectSmpe() - installationTypePage.enterRuntimeDir('ABCDE') - installationTypePage.clickValidateLocation() - await page.waitForTimeout(5000) - const is_GreenCheck_Visible = await installationTypePage.isValidateLocationGreenCheckVisible(); - expect(is_GreenCheck_Visible).toBe(false); - const Is_Continue_Button_Enable = await installationTypePage.isContinueToComponentInstallationEnabled(); - expect(Is_Continue_Button_Enable).toBe(false); - }) - - test('Test SMPE with Empty Path', async ({ page }) => { - await page.waitForTimeout(5000) - installationTypePage.selectSmpe() - installationTypePage.enterRuntimeDir('') - installationTypePage.clickValidateLocation() - await page.waitForTimeout(5000) - const is_GreenCheck_Visible = await installationTypePage.isValidateLocationGreenCheckVisible(); - expect(is_GreenCheck_Visible).toBe(false); - const Is_Continue_Button_Enable = await installationTypePage.isContinueToComponentInstallationEnabled(); - expect(Is_Continue_Button_Enable).toBe(false); - }) - test('Test Previous step', async ({ page }) => { - installationTypePage.clickPreviousStep(); - await page.waitForTimeout(2000); + await installationTypePage.clickPreviousStep(); const title = await planningPage.getPlanningPageTitle(); expect(title).toBe(PLANNING_TITLE); }) test('Test Continue To Components Installation Button', async ({ page }) => { - await page.waitForTimeout(5000) - installationTypePage.selectDownloadZowePax() - installationTypePage.clickLicenseAgreement() - installationTypePage.clickAgreeLicense() - const Is_Continue_Button_Enable = await installationTypePage.isContinueToComponentInstallationEnabled(); + await installationTypePage.selectDownloadZowePax() + await installationTypePage.clickLicenseAgreement() + await installationTypePage.clickAgreeLicense() + const Is_Continue_Button_Enable = await installationTypePage.isContinueUnpaxEnabled(); expect(Is_Continue_Button_Enable).toBe(true); - installationTypePage.clickContinueToInstallation() + await installationTypePage.continueToUnpax() const title = await installationPage.getInstallationPageTitle(); - expect(title).toBe(INSTALLATION_PAGE_TITLE); + expect(title).toBe(DOWNLOAD_ZOWE_PAX); }) test('Test Save and Close and Resume Progress', async ({page}) => { - await page.waitForTimeout(5000) - installationTypePage.selectDownloadZowePax() - installationTypePage.clickLicenseAgreement() - installationTypePage.clickAgreeLicense() - const Is_Continue_Button_Enable = await installationTypePage.isContinueToComponentInstallationEnabled(); + await installationTypePage.selectDownloadZowePax() + await installationTypePage.clickLicenseAgreement() + await installationTypePage.clickAgreeLicense() + const Is_Continue_Button_Enable = await installationTypePage.isContinueUnpaxEnabled(); expect(Is_Continue_Button_Enable).toBe(true); - installationTypePage.clickSaveAndClose(); - await page.waitForTimeout(3000); - titlePage.clickOnResumeProgress(); - await page.waitForTimeout(5000); + await installationTypePage.clickSaveAndClose(); + await titlePage.clickOnResumeProgress(); + await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); const is_GreenCheck_Visible = await installationTypePage.isLicenseAgreementGreenCheckVisible(); expect(is_GreenCheck_Visible).toBe(true); - const Is_Continue_Button_Enable_After_Save = await installationTypePage.isContinueToComponentInstallationEnabled(); + const Is_Continue_Button_Enable_After_Save = await installationTypePage.isContinueUnpaxEnabled(); expect(Is_Continue_Button_Enable_After_Save).toBe(true); }) }) \ No newline at end of file diff --git a/playwright_test/Tests/Networking.spec.ts b/playwright_test/Tests/Networking.spec.ts index ca101094..55202448 100644 --- a/playwright_test/Tests/Networking.spec.ts +++ b/playwright_test/Tests/Networking.spec.ts @@ -4,9 +4,12 @@ import ApfAuthPage from '../Pages/ApfAuth.page'; import { prepareEnvironment } from '../prepare.js'; import TitlePage from '../Pages/title.page'; import ConnectionPage from '../Pages/connection.page'; +import InstallationPage from '../Pages/installation.page.ts'; +import InstallationTypePage from '../Pages/installationType.page.ts'; import PlanningPage from '../Pages/planning.page'; import NetworkingPage from '../Pages/networking.page'; import path from 'path'; +import config from '../utils/config'; let page: Page; @@ -14,23 +17,7 @@ let electronApp: ElectronApplication const NETWORKING_TITLE = 'Networking'; const APFAUTH_TITLE = 'APF Authorize Load Libraries'; const INSTALLATION_TITLE = 'Installation'; -const DOMAIN_NAME = process.env.DOMAIN_NAME; -const EXTERNAL_PORT = process.env.EXTERNAL_PORT; -const ZOWE_ROOT_DIR = process.env.ZOWE_ROOT_DIR; -const SSH_HOST = process.env.SSH_HOST; -const SSH_PASSWD = process.env.SSH_PASSWD; -const SSH_PORT = process.env.SSH_PORT; -const SSH_USER = process.env.SSH_USER; -const ZOWE_EXTENSION_DIR= process.env.ZOWE_EXTENSION_DIR; -const ZOWE_LOG_DIR=process.env.ZOWE_LOG_DIR; -const ZOWE_WORKSPACE_DIR=process.env.ZOWE_WORKSPACE_DIR; -const JOB_NAME= process.env.JOB_NAME; -const JOB_PREFIX=process.env.JOB_PREFIX; -const JAVA_HOME=process.env.JAVA_HOME; -const NODE_HOME=process.env.NODE_HOME; -const ZOSMF_HOST=process.env.ZOSMF_HOST; -const ZOSMF_PORT=process.env.ZOSMF_PORT; -const ZOSMF_APP_ID=process.env.ZOSMF_APP_ID; + test.beforeAll(async () => { try { @@ -47,30 +34,51 @@ test.describe('networkingTab', () => { let securityPage : SecurityPage; let planningPage : PlanningPage; let networkingPage : NetworkingPage; + let installationTypePage : InstallationTypePage; + let installationPage : InstallationPage; test.beforeEach(async ({ page }) => { test.setTimeout(900000); electronApp = await electron.launch({ args: ['.webpack/main/index.js'] }) - page= await electronApp.firstWindow() + page = await electronApp.firstWindow() connectionPage = new ConnectionPage(page); networkingPage = new NetworkingPage(page); titlePage = new TitlePage(page); planningPage = new PlanningPage(page); + installationPage = new InstallationPage(page); + installationTypePage = new InstallationTypePage(page); titlePage.navigateToConnectionTab() - connectionPage.fillConnectionDetails(SSH_HOST,SSH_PORT,SSH_USER,SSH_PASSWD) - connectionPage.SubmitValidateCredential() - await page.waitForTimeout(5000); - connectionPage.clickContinueButton() - planningPage.clickSaveValidate() - await page.waitForTimeout(20000); - planningPage.fillPlanningPageWithRequiredFields(ZOWE_ROOT_DIR, ZOWE_WORKSPACE_DIR,ZOWE_EXTENSION_DIR,ZOWE_LOG_DIR,'1',JOB_NAME,JOB_PREFIX,JAVA_HOME,NODE_HOME,ZOSMF_HOST,ZOSMF_PORT,ZOSMF_APP_ID) - await page.waitForTimeout(20000); - planningPage.clickValidateLocations() - await page.waitForTimeout(20000); - planningPage.clickContinueToInstallation() - await page.waitForTimeout(5000); - networkingPage.movetoNetworkingPage() - await page.waitForTimeout(5000); + await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); + await connectionPage.SubmitValidateCredential(); + await connectionPage.clickContinueButton(); + await planningPage.fillPlanningPageWithRequiredFields(config.ZOWE_ROOT_DIR, + config.ZOWE_WORKSPACE_DIR, + config.ZOWE_EXTENSION_DIR, + config.ZOWE_LOG_DIR, + '1', + config.JOB_NAME, + config.JOB_PREFIX, + config.JAVA_HOME, + config.NODE_HOME, + config.ZOSMF_HOST, + config.ZOSMF_PORT, + config.ZOSMF_APP_ID + ); + await planningPage.clickValidateLocations() + await planningPage.clickContinueToInstallation() + await installationTypePage.downloadZowePaxAndNavigateToInstallationPage() + await installationTypePage.continueToUnpax() + await installationTypePage.skipUnpax() + await installationPage.fillAllFields(config.DATASET_PREFIX, + config.PARM_LIB, + config.PROC_LIB, + config.JCL_LIB, + config.LOAD_LIB, + config.AUTH_LOAD_LIB, + config.AUTH_PLUGIN_LIB + ) + await installationPage.clickInstallMvsDatasets(); + await installationPage.clickContinueToNetworkSetup(); }) test.afterEach(async () => { @@ -78,12 +86,11 @@ test.describe('networkingTab', () => { }) test('test title of page', async ({ page }) => { - await page.waitForTimeout(5000); const title = await networkingPage.returnTitleOfNetworkingPage(); expect(title).toBe(NETWORKING_TITLE); }) + test('test all required fields', async ({ page }) => { - await page.waitForTimeout(5000); await expect(networkingPage.externalDomains).toBeTruthy() await expect(networkingPage.externalPort).toBeTruthy() await expect(networkingPage.components).toBeTruthy() @@ -101,135 +108,86 @@ test.describe('networkingTab', () => { await expect(networkingPage.appServer).toBeTruthy() await expect(networkingPage.cachingService).toBeTruthy() await expect(networkingPage.discovery).toBeTruthy() - }) test('test external domain field', async ({ page }) => { - await page.waitForTimeout(5000); - await networkingPage.fillexternal_domainvalues(DOMAIN_NAME,EXTERNAL_PORT); - await page.waitForTimeout(5000); + await networkingPage.fillexternal_domainvalues(config.DOMAIN_NAME, config.EXTERNAL_PORT); const port = await networkingPage.get_externalDomainport_value(); const domainName = await networkingPage.get_externalDomainName_value(); - console.log(port,domainName) - expect(port).toBe(DOMAIN_NAME); - expect(domainName).toBe(EXTERNAL_PORT); - await page.waitForTimeout(5000); + expect(port).toBe(config.EXTERNAL_PORT); + expect(domainName).toBe(config.DOMAIN_NAME); }) test('test deleting domain name field', async ({ page }) => { await networkingPage.delete_DomainNameField(); - await page.waitForTimeout(5000); const isDomainNameVisible = await networkingPage.domainName.isVisible(); expect(isDomainNameVisible).toBeFalsy() }) test('test add more domain name field', async ({ page }) => { - await page.waitForTimeout(5000); await networkingPage.add_DomainNameField(); - await page.waitForTimeout(5000); await expect(networkingPage.domainName).toBeTruthy() }) + test('test add special char in other port no', async ({ page }) => { - await page.waitForTimeout(5000); + const originalValue = await networkingPage.get_metricServiceport_value(); await networkingPage.fillMetricServicePort('*^%$^&'); - await page.waitForTimeout(5000); - const port = await networkingPage.get_metricServiceport_value(); - expect(port).toBe(''); + const newValue = await networkingPage.get_metricServiceport_value(); + expect(newValue).toBe(originalValue); }) - test('test enabled debug component', async ({ page }) => { - await page.waitForTimeout(5000); - await networkingPage.click_checkBox('1'); - await networkingPage.click_checkBox('2'); - await page.waitForTimeout(10000); - const isEnabled = await networkingPage.isCheckboxCheckedAndBlue('2'); - const isDebug = await networkingPage.isCheckboxCheckedAndBlue('1'); - expect(isEnabled).toBe(true); - expect(isDebug).toBe(true); + test('test enabled metric service debug', async ({ page }) => { + const beforeClick = await networkingPage.isMetricsServiceDebugChecked(); + expect(beforeClick).toBe(false); + await networkingPage.clickMetricsServiceDebug(); + const afterClick = await networkingPage.isMetricsServiceDebugChecked(); + expect(afterClick).toBe(true); }) test('Test view yaml button', async ({ page }) => { - await page.waitForTimeout(7000); - networkingPage.viewYaml() - await page.waitForTimeout(5000); + await networkingPage.viewYaml() await expect(networkingPage.editor_title_element).toBeTruthy(); - await page.waitForTimeout(5000); - networkingPage.closeButton() - await page.waitForTimeout(2000); - }) - - test('Test view and submit button', async ({ page }) => { - await page.waitForTimeout(5000); - networkingPage.click_viewAndSubmitJob() - await page.waitForTimeout(5000); - await expect(networkingPage.editor_title_element).toBeTruthy() - networkingPage.closeButton() - await page.waitForTimeout(2000); + await networkingPage.closeButton() }) - test('Test view job', async ({ page }) => { - await page.waitForTimeout(5000); - networkingPage.click_previewJob() - await page.waitForTimeout(5000); - await expect(networkingPage.editor_title_element).toBeTruthy() - networkingPage.closeButton() - await page.waitForTimeout(5000); - }) - test('Test save and close', async ({ page }) => { - await page.waitForTimeout(5000); - await networkingPage.fillexternal_domainvalues(DOMAIN_NAME,EXTERNAL_PORT); - await page.waitForTimeout(5000); - networkingPage.click_saveAndClose() - await page.waitForTimeout(3000); - titlePage.clickOnResumeProgress(); - await page.waitForTimeout(15000); + await networkingPage.fillexternal_domainvalues(config.DOMAIN_NAME, config.EXTERNAL_PORT); + await networkingPage.click_saveAndClose() + await titlePage.clickOnResumeProgress(); + await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); + await connectionPage.SubmitValidateCredential(); const title = await networkingPage.returnTitleOfNetworkingPage(); expect(title).toBe(NETWORKING_TITLE); const port = await networkingPage.get_externalDomainport_value(); const domainName = await networkingPage.get_externalDomainName_value(); - expect(port).toBe(EXTERNAL_PORT); - expect(domainName).toBe(DOMAIN_NAME); - await page.waitForTimeout(5000); - + expect(port).toBe(config.EXTERNAL_PORT); + expect(domainName).toBe(config.DOMAIN_NAME); }) test('click Previous step button', async ({ page }) => { - await page.waitForTimeout(5000); - const title = await networkingPage.returnTitleOfPrevPage(); - expect(title).toBe(INSTALLATION_TITLE); - }) - test('Test previous button is enabled', async ({ page }) => { const is_prevButtonEnable = await networkingPage.isPreviousButtonEnable(); expect(is_prevButtonEnable).toBe(true); - await page.waitForTimeout(2000); + const title = await networkingPage.returnTitleOfPrevPage(); + expect(title).toBe(INSTALLATION_TITLE); }) test('Test continue to APF Auth button is disable', async ({ page }) => { - await page.waitForTimeout(2000); const is_ContinueButtonDisable = await networkingPage.isContinueButtonDisable(); expect(is_ContinueButtonDisable).toBe(true); - await page.waitForTimeout(2000); }) + test('Test Skip networking button is enable', async ({ page }) => { - await page.waitForTimeout(2000); const isLaunchConfigEnable = await networkingPage.is_skipNetworkingButtonEnable(); expect(isLaunchConfigEnable).toBe(true); - await page.waitForTimeout(2000); }) test('Test yaml should be updated', async ({ page }) => { - await page.waitForTimeout(5000); - await networkingPage.fillexternal_domainvalues(DOMAIN_NAME,EXTERNAL_PORT); - await page.waitForTimeout(5000); + await networkingPage.fillexternal_domainvalues(config.DOMAIN_NAME, config.EXTERNAL_PORT); await networkingPage.viewYaml(); - await page.waitForTimeout(10000); await expect(networkingPage.editor_title_element).toBeTruthy(); - await page.waitForTimeout(5000); const yaml = await networkingPage.read_yaml(); - await page.waitForTimeout(5000); - expect(yaml).toContain(DOMAIN_NAME); - expect(yaml).toContain(EXTERNAL_PORT); + expect(yaml).toContain(config.DOMAIN_NAME); + expect(yaml).toContain(config.EXTERNAL_PORT); }) }); diff --git a/playwright_test/Tests/Planning.spec.ts b/playwright_test/Tests/Planning.spec.ts index 61ed9f54..f05de8d6 100644 --- a/playwright_test/Tests/Planning.spec.ts +++ b/playwright_test/Tests/Planning.spec.ts @@ -5,31 +5,15 @@ import PlanningPage from '../Pages/planning.page.ts'; import InstallationTypePage from '../Pages/installationType.page.ts'; import path from 'path'; let page: Page; +import config from '../utils/config'; let electronApp: ElectronApplication const CONNECTION_PAGE_TITLE = 'Connection'; -const SSH_HOST = process.env.SSH_HOST; -const SSH_PASSWD = process.env.SSH_PASSWD; -const SSH_PORT = process.env.SSH_PORT; -const SSH_USER = process.env.SSH_USER; const PLANNING_TITLE = 'Before you start'; const INSTALLATION_TYPE_TITLE = 'Installation Type'; -const JOB_STATEMENT = "//HELLOJOB JOB 'HELLO, WORLD!',CLASS=A,MSGCLASS=A\n//STEP01 EXEC PGM=IEFBR14\n//SYSPRINT DD SYSOUT=A\n//SYSIN DD DUMMY"; const INVALID_JOB_STATEMENT = "//HELLOJOB JOB 'HELLO, WORLD!',CLASS=A,MSGCLASS"; -const ERROR_MESSAGE = "Failed to verify job statement"; -const RUNTIME_DIR = process.env.ZOWE_ROOT_DIR; -const WORKSPACE_DIR = process.env.ZOWE_WORKSPACE_DIR; -const LOG_DIR = process.env.ZOWE_LOG_DIR; -const EXTENSIONS_DIR = process.env.ZOWE_EXTENSION_DIR; -const RBAC_IDENTIFIER = '1'; -const JOB_NAME = process.env.JOB_NAME; -const JOB_PREFIX = process.env.JOB_PREFIX; -const COOKIE_IDENTIFIER = '1'; -const JAVA_LOCATION = process.env.JAVA_HOME; -const NODEJS_LOCATION = process.env.NODE_HOME; -const ZOSMF_HOST=process.env.ZOSMF_HOST; -const ZOSMF_PORT=process.env.ZOSMF_PORT; -const ZOSMF_APP_ID=process.env.ZOSMF_APP_ID; +const ERROR_MESSAGE = "Failed to verify job statement STMT NO. MESSAGE\n 1 IEFC006I POSITIONAL PARAMETERS MUST BE SPECIFIED BEFORE KEYWORD PARAMETERS"; +const EMPTY_ERROR = "Error invoking remote method 'get-env-vars': Error: Failed to submit jcl, job id not found"; test.describe('PlanningTab', () => { let connectionPage: ConnectionPage; @@ -40,18 +24,15 @@ test.describe('PlanningTab', () => { test.beforeEach(async () => { test.setTimeout(900000); electronApp = await electron.launch({ args: ['.webpack/main/index.js'] }) - page= await electronApp.firstWindow() + page = await electronApp.firstWindow() connectionPage = new ConnectionPage(page); titlePage = new TitlePage(page); planningPage = new PlanningPage(page); installationTypePage = new InstallationTypePage(page); titlePage.navigateToConnectionTab(); - connectionPage.fillConnectionDetails(SSH_HOST,SSH_PORT,SSH_USER,SSH_PASSWD) - connectionPage.SubmitValidateCredential(); - await page.waitForTimeout(5000); - connectionPage.clickContinueButton(); - await page.waitForTimeout(3000); - + await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); + await connectionPage.SubmitValidateCredential(); + await connectionPage.clickContinueButton(); }) test.afterEach(async () => { @@ -66,17 +47,14 @@ test.describe('PlanningTab', () => { }) test('Test Valid Job Statement and Save Validate', async () => { - planningPage.enterJobStatement(JOB_STATEMENT); - planningPage.clickSaveAndValidate(); - await page.waitForTimeout(20000); + await planningPage.clickSaveValidate(); const isGreen_check_visible = await planningPage.isSaveAndValidateGreenCheckVisible(); expect(isGreen_check_visible).toBe(true); }) test('Test Invalid Job Statement and Save Validate', async () => { - planningPage.enterJobStatement(INVALID_JOB_STATEMENT); - planningPage.clickSaveAndValidate(); - await page.waitForTimeout(20000); + await planningPage.enterJobStatement(INVALID_JOB_STATEMENT); + await planningPage.clickSaveAndValidate(); const error_Message = await planningPage.getErrorMessage() expect (error_Message).toBe(ERROR_MESSAGE); const isGreen_check_visible = await planningPage.isSaveAndValidateGreenCheckVisible(); @@ -84,19 +62,17 @@ test.describe('PlanningTab', () => { }) test('Test Empty Job Statement and Save Validate', async () => { - planningPage.enterJobStatement(''); - planningPage.clickSaveAndValidate(); + await planningPage.enterJobStatement(''); + await planningPage.clickSaveAndValidate(); await page.waitForTimeout(20000); const error_Message = await planningPage.getErrorMessage() - expect (error_Message).toBe(ERROR_MESSAGE); + expect (error_Message).toBe(EMPTY_ERROR); const isGreen_check_visible = await planningPage.isSaveAndValidateGreenCheckVisible(); expect(isGreen_check_visible).toBe(false); }) test('Test all required fields on Planning Tab After Job Validation', async () => { - planningPage.enterJobStatement(JOB_STATEMENT); - planningPage.clickSaveAndValidate(); - await page.waitForTimeout(20000); + await planningPage.clickSaveValidate(); expect(planningPage.runtimeDir).toBeTruthy(); expect(planningPage.workspaceDir).toBeTruthy(); expect(planningPage.logsDir).toBeTruthy(); @@ -120,84 +96,43 @@ test.describe('PlanningTab', () => { }) test('Test Validate Locations with Valid Data', async () => { - planningPage.enterJobStatement(JOB_STATEMENT); - planningPage.clickSaveAndValidate(); - await page.waitForTimeout(20000); - planningPage.enterRuntimeDir(RUNTIME_DIR); - await page.waitForTimeout(2000); - planningPage.enterWorkspaceDir(WORKSPACE_DIR); - await page.waitForTimeout(2000); - planningPage.enterLogsDir(LOG_DIR); - await page.waitForTimeout(2000); - planningPage.enterExtensionsDir(EXTENSIONS_DIR); - await page.waitForTimeout(2000); - planningPage.enterRbacProfileIdentifier(RBAC_IDENTIFIER); - await page.waitForTimeout(2000); - planningPage.enterJobName(JOB_NAME); - await page.waitForTimeout(2000); - planningPage.enterJobPrefix(JOB_PREFIX); - await page.waitForTimeout(2000); - planningPage.enterCookieIdentifier(COOKIE_IDENTIFIER); - await page.waitForTimeout(2000); - planningPage.enterJavaLocation(JAVA_LOCATION); - await page.waitForTimeout(2000); - planningPage.enterNodeJsLocation(NODEJS_LOCATION); - await page.waitForTimeout(2000); - planningPage.checkSetZosmfAttribute(); - await page.waitForTimeout(2000); - planningPage.enterZosmfHost(ZOSMF_HOST); - await page.waitForTimeout(2000); - planningPage.enterZosmfPort(ZOSMF_PORT); - await page.waitForTimeout(2000); - planningPage.enterZosmfApplicationId(ZOSMF_APPID); - await page.waitForTimeout(2000); - planningPage.clickValidateLocations(); - await page.waitForTimeout(20000); + await planningPage.fillPlanningPageWithRequiredFields(config.ZOWE_ROOT_DIR, + config.ZOWE_WORKSPACE_DIR, + config.ZOWE_EXTENSION_DIR, + config.ZOWE_LOG_DIR, + '1', + config.JOB_NAME, + config.JOB_PREFIX, + config.JAVA_HOME, + config.NODE_HOME, + config.ZOSMF_HOST, + config.ZOSMF_PORT, + config.ZOSMF_APP_ID + ); + await planningPage.clickValidateLocations() const is_GreenCheck_Visible = await planningPage.isValidateLocationsGreenCheckVisible(); expect(is_GreenCheck_Visible).toBe(true); const is_Continue_Button_enable = await planningPage.isContinueToInstallationEnabled(); expect(is_Continue_Button_enable).toBe(true); - planningPage.clickContinueToInstallation(); - await page.waitForTimeout(2000); + await planningPage.clickContinueToInstallation(); const installationType_title = await installationTypePage.getInstallationTypePageTitle() expect (installationType_title).toBe(INSTALLATION_TYPE_TITLE); }) test('Test Validate Locations with Invalid Data', async () => { - await page.waitForTimeout(2000); - planningPage.enterJobStatement(JOB_STATEMENT); - planningPage.clickSaveAndValidate(); - await page.waitForTimeout(20000); - planningPage.enterRuntimeDir('Test/DIR'); - await page.waitForTimeout(2000); - planningPage.enterWorkspaceDir('Workspace Dir'); - await page.waitForTimeout(2000); - planningPage.enterLogsDir(LOG_DIR); - await page.waitForTimeout(2000); - planningPage.enterExtensionsDir(EXTENSIONS_DIR); - await page.waitForTimeout(2000); - planningPage.enterRbacProfileIdentifier(22); - await page.waitForTimeout(2000); - planningPage.enterJobName(JOB_NAME); - await page.waitForTimeout(2000); - planningPage.enterJobPrefix(JOB_PREFIX); - await page.waitForTimeout(2000); - planningPage.enterCookieIdentifier(99999); - await page.waitForTimeout(2000); - planningPage.enterJavaLocation('/'); - await page.waitForTimeout(2000); - planningPage.enterNodeJsLocation(NODEJS_LOCATION); - await page.waitForTimeout(2000); - planningPage.checkSetZosmfAttribute(); - await page.waitForTimeout(2000); - planningPage.enterZosmfHost(ZOSMF_HOST); - await page.waitForTimeout(2000); - planningPage.enterZosmfPort(987776); - await page.waitForTimeout(2000); - planningPage.enterZosmfApplicationId('ABCDDDETT'); - await page.waitForTimeout(2000); - planningPage.clickValidateLocations(); - await page.waitForTimeout(20000); + await planningPage.clickSaveValidate(); + await planningPage.enterRuntimeDir('Test/DIR'); + await planningPage.enterWorkspaceDir('Workspace Dir'); + await planningPage.enterLogsDir(config.ZOWE_LOG_DIR); + await planningPage.enterExtensionsDir(config.ZOWE_EXTENSION_DIR); + await planningPage.enterRbacProfileIdentifier('TEST'); + await planningPage.enterJobName(config.JOB_NAME); + await planningPage.enterJobPrefix(config.JOB_PREFIX); + await planningPage.enterCookieIdentifier('9999'); + await planningPage.enterJavaLocation('/'); + await planningPage.enterNodeJsLocation(config.NODE_HOME); + await planningPage.enterZosmfApplicationId('ABCDDDETT'); + await planningPage.clickValidateLocations(); const is_GreenCheck_Visible = await planningPage.isValidateLocationsGreenCheckVisible(); expect(is_GreenCheck_Visible).toBe(false); const is_Continue_Button_enable = await planningPage.isContinueToInstallationEnabled(); @@ -205,42 +140,30 @@ test.describe('PlanningTab', () => { }) test('Test Previous step', async ({ page }) => { - planningPage.clickPreviousStep(); - await page.waitForTimeout(2000); + await planningPage.clickPreviousStep(); const title = await connectionPage.getConnectionPageTitle(); expect(title).toBe(CONNECTION_PAGE_TITLE); }) test('Test Save and Close and Resume Progress', async () => { - planningPage.enterJobStatement(JOB_STATEMENT); - planningPage.clickSaveAndValidate(); - await page.waitForTimeout(20000); - planningPage.enterRuntimeDir(RUNTIME_DIR); - await page.waitForTimeout(2000); - planningPage.enterWorkspaceDir(WORKSPACE_DIR); - await page.waitForTimeout(2000); - planningPage.enterLogsDir(LOG_DIR); - await page.waitForTimeout(2000); - planningPage.enterExtensionsDir(EXTENSIONS_DIR); - await page.waitForTimeout(2000); - planningPage.enterRbacProfileIdentifier(RBAC_IDENTIFIER); - await page.waitForTimeout(2000); - planningPage.enterJobName(JOB_NAME); - await page.waitForTimeout(2000); - planningPage.enterJobPrefix(JOB_PREFIX); - await page.waitForTimeout(2000); - planningPage.enterCookieIdentifier(COOKIE_IDENTIFIER); - await page.waitForTimeout(2000); - planningPage.enterJavaLocation(JAVA_LOCATION); - await page.waitForTimeout(2000); - planningPage.enterNodeJsLocation(NODEJS_LOCATION); - await page.waitForTimeout(2000); - planningPage.clickValidateLocations(); - await page.waitForTimeout(20000); - planningPage.clickSaveAndClose(); - await page.waitForTimeout(3000); - titlePage.clickOnResumeProgress(); - await page.waitForTimeout(5000); + await planningPage.fillPlanningPageWithRequiredFields(config.ZOWE_ROOT_DIR, + config.ZOWE_WORKSPACE_DIR, + config.ZOWE_EXTENSION_DIR, + config.ZOWE_LOG_DIR, + '1', + config.JOB_NAME, + config.JOB_PREFIX, + config.JAVA_HOME, + config.NODE_HOME, + config.ZOSMF_HOST, + config.ZOSMF_PORT, + config.ZOSMF_APP_ID + ); + await planningPage.clickValidateLocations() + await planningPage.clickSaveAndClose(); + await titlePage.clickOnResumeProgress(); + await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); + await connectionPage.SubmitValidateCredential(); const title = await planningPage.getPlanningPageTitle(); expect(title).toBe(PLANNING_TITLE); const is_GreenCheck_Visible = await planningPage.isValidateLocationsGreenCheckVisible(); diff --git a/playwright_test/Tests/Security.spec.ts b/playwright_test/Tests/Security.spec.ts index 2f3af785..3a296d04 100644 --- a/playwright_test/Tests/Security.spec.ts +++ b/playwright_test/Tests/Security.spec.ts @@ -5,7 +5,11 @@ import ApfAuthPage from '../Pages/ApfAuth.page'; import TitlePage from '../Pages/title.page'; import ConnectionPage from '../Pages/connection.page'; import PlanningPage from '../Pages/planning.page'; +import NetworkingPage from '../Pages/networking.page'; +import InstallationPage from '../Pages/installation.page.ts'; +import InstallationTypePage from '../Pages/installationType.page.ts'; import path from 'path'; +import config from '../utils/config'; let page: Page; @@ -13,29 +17,8 @@ let electronApp: ElectronApplication const CERTIFICATE_TITLE = 'Certificates' const SECURITY_TITLE = 'Security' const APF_AUTH_TITLE ='APF Authorize Load Libraries' -const ZOWE_ROOT_DIR = process.env.ZOWE_ROOT_DIR; -const SSH_HOST = process.env.SSH_HOST; -const SSH_PASSWD = process.env.SSH_PASSWD; -const SSH_PORT = process.env.SSH_PORT; -const SSH_USER = process.env.SSH_USER; -const ZOWE_EXTENSION_DIR= process.env.ZOWE_EXTENSION_DIR; -const ZOWE_LOG_DIR=process.env.ZOWE_LOG_DIR; -const ZOWE_WORKSPACE_DIR=process.env.ZOWE_WORKSPACE_DIR; -const JOB_NAME= process.env.JOB_NAME; -const JOB_PREFIX=process.env.JOB_PREFIX; -const JAVA_HOME=process.env.JAVA_HOME; -const NODE_HOME=process.env.NODE_HOME; -const ZOSMF_HOST=process.env.ZOSMF_HOST; -const ZOSMF_PORT=process.env.ZOSMF_PORT; -const ZOSMF_APP_ID=process.env.ZOSMF_APP_ID; -const SECURITY_ADMIN= process.env.SECURITY_ADMIN; -const SECURITY_STC = process.env.SECURITY_STC; -const SECURITY_SYSPROG = process.env.SECURITY_SYSPROG; -const SECURITY_USER_ZIS = process.env.SECURITY_USER_ZIS; -const SECURITY_USER_ZOWE = process.env.SECURITY_USER_ZOWE; -const SECURITY_AUX = process.env.SECURITY_AUX; -const SECURITY_STC_ZOWE = process.env.SECURITY_STC_ZOWE; -const SECURITY_STC_ZIS = process.env.SECURITY_STC_ZIS; +const STC_TITTLE = 'Stcs' + test.beforeAll(async () => { try { @@ -52,6 +35,9 @@ test.describe('securityTab', () => { let securityPage : SecurityPage; let planningPage : PlanningPage; let apfAuthPage : ApfAuthPage; + let networkingPage : NetworkingPage; + let installationTypePage : InstallationTypePage; + let installationPage : InstallationPage; test.beforeEach(async ({ page }) => { @@ -61,23 +47,45 @@ test.describe('securityTab', () => { connectionPage = new ConnectionPage(page); titlePage = new TitlePage(page); planningPage = new PlanningPage(page); + networkingPage = new NetworkingPage(page); apfAuthPage = new ApfAuthPage(page); securityPage = new SecurityPage(page); + installationPage = new InstallationPage(page); + installationTypePage = new InstallationTypePage(page); titlePage.navigateToConnectionTab() - connectionPage.fillConnectionDetails(SSH_HOST,SSH_PORT,SSH_USER,SSH_PASSWD) - connectionPage.SubmitValidateCredential() - await page.waitForTimeout(5000); - connectionPage.clickContinueButton() - planningPage.clickSaveValidate() - await page.waitForTimeout(20000); - planningPage.fillPlanningPageWithRequiredFields(ZOWE_ROOT_DIR, ZOWE_WORKSPACE_DIR,ZOWE_EXTENSION_DIR,ZOWE_LOG_DIR,'1',JOB_NAME,JOB_PREFIX,JAVA_HOME,NODE_HOME,ZOSMF_HOST,ZOSMF_PORT,ZOSMF_APP_ID) - await page.waitForTimeout(20000); - planningPage.clickValidateLocations() - await page.waitForTimeout(20000); - planningPage.clickContinueToInstallation() - await page.waitForTimeout(5000); - securityPage.movetoSecurityPage() - await page.waitForTimeout(5000); + await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); + await connectionPage.SubmitValidateCredential(); + await connectionPage.clickContinueButton(); + await planningPage.fillPlanningPageWithRequiredFields(config.ZOWE_ROOT_DIR, + config.ZOWE_WORKSPACE_DIR, + config.ZOWE_EXTENSION_DIR, + config.ZOWE_LOG_DIR, + '1', + config.JOB_NAME, + config.JOB_PREFIX, + config.JAVA_HOME, + config.NODE_HOME, + config.ZOSMF_HOST, + config.ZOSMF_PORT, + config.ZOSMF_APP_ID + ); + await planningPage.clickValidateLocations() + await planningPage.clickContinueToInstallation() + await installationTypePage.downloadZowePaxAndNavigateToInstallationPage() + await installationTypePage.continueToUnpax() + await installationTypePage.skipUnpax() + await installationPage.fillAllFields(config.DATASET_PREFIX, + config.PARM_LIB, + config.PROC_LIB, + config.JCL_LIB, + config.LOAD_LIB, + config.AUTH_LOAD_LIB, + config.AUTH_PLUGIN_LIB + ) + await installationPage.clickInstallMvsDatasets(); + await installationPage.clickContinueToNetworkSetup(); + await networkingPage.click_skipNetworking() + await apfAuthPage.click_skipApfAuth() }) test.afterEach(async () => { @@ -85,7 +93,6 @@ test.describe('securityTab', () => { }) test('Test all required fields on security page', async ({ page }) => { - await page.waitForTimeout(5000); await expect(securityPage.product).toBeTruthy() await expect(securityPage.admin).toBeTruthy() await expect(securityPage.stc).toBeTruthy() @@ -102,108 +109,74 @@ test.describe('securityTab', () => { await expect(securityPage.continue_CertificateSelector).toBeTruthy() }) - test('test security with empty data', async ({ page }) => { - await page.waitForTimeout(5000); - securityPage.fillSecurityDetails('','','','','','','','','') - await page.waitForTimeout(5000); - securityPage.initializeSecurity() - await page.waitForTimeout(15000); - const isWriteConfig_check_visible = await securityPage.isWriteConfigGreenCheckVisible(); - expect(isWriteConfig_check_visible).toBe(false); - const isUploadConfig_check_visible = await securityPage.isUploadConfigGreenCheckVisible(); - expect(isUploadConfig_check_visible).toBe(false); - const isInitSecurity_check_visible = await securityPage.isInitSecurityGreenCheckVisible(); - expect(isInitSecurity_check_visible).toBe(false); - await page.waitForTimeout(15000); - - }) + //needs to be done test('test security with valid data', async ({ page }) => { - await page.waitForTimeout(5000); - securityPage.fillSecurityDetails('RACF',SECURITY_ADMIN,SECURITY_STC,SECURITY_SYSPROG,SECURITY_USER_ZIS,SECURITY_USER_ZOWE,SECURITY_AUX,SECURITY_STC_ZOWE,SECURITY_STC_ZIS) - await page.waitForTimeout(5000); - securityPage.initializeSecurity() - await page.waitForTimeout(5000); - const isWriteConfig_check_visible = await securityPage.isWriteConfigGreenCheckVisible(); - expect(isWriteConfig_check_visible).toBe(true); - const isUploadConfig_check_visible = await securityPage.isUploadConfigGreenCheckVisible(); - expect(isUploadConfig_check_visible).toBe(true); - const isInitSecurity_check_visible = await securityPage.isInitSecurityGreenCheckVisible(); - expect(isInitSecurity_check_visible).toBe(true); - await page.waitForTimeout(5000); - + await securityPage.fillSecurityDetails('RACF', + config.SECURITY_ADMIN, + config.SECURITY_STC, + config.SECURITY_SYSPROG, + config.SECURITY_USER_ZIS, + config.SECURITY_USER_ZOWE, + config.SECURITY_AUX, + config.SECURITY_STC_ZOWE, + config.SECURITY_STC_ZIS + ) + await securityPage.initializeSecurity() + const is_ContinueButtonDisable = await securityPage.isContinueButtonDisable(); + expect(is_ContinueButtonDisable).toBe(false); }) test('click Previous step button', async ({ page }) => { - await page.waitForTimeout(5000); + const is_prevButtonEnable = await securityPage.isPreviousButtonEnable(); + expect(is_prevButtonEnable).toBe(true); const title = await securityPage.returnTitleOfPrevPage(); expect(title).toBe(APF_AUTH_TITLE); }) test('test click skip security button', async ({ page }) => { - await page.waitForTimeout(5000); - const certificate_title = await securityPage.click_skipSecurity(); - expect(certificate_title).toBe(CERTIFICATE_TITLE); + const isSkipSecurityEnable = await securityPage.is_skipSecurityButtonEnable(); + expect(isSkipSecurityEnable).toBe(true); + await securityPage.click_skipSecurity(); + const title = await securityPage.returnTitleOfstcPage() + expect(title).toBe(STC_TITTLE); }) - test('Test previous button is enabled', async ({ page }) => { - const is_prevButtonEnable = await securityPage.isPreviousButtonEnable(); - expect(is_prevButtonEnable).toBe(true); - await page.waitForTimeout(2000); - }) - test('Test continue to certificate button is disable', async ({ page }) => { - await page.waitForTimeout(2000); const is_ContinueButtonDisable = await securityPage.isContinueButtonDisable(); expect(is_ContinueButtonDisable).toBe(true); - await page.waitForTimeout(2000); - }) - - test('Test Skip security button is enable', async ({ page }) => { - await page.waitForTimeout(2000); - const isSkipSecurityEnable = await securityPage.is_skipSecurityButtonEnable(); - expect(isSkipSecurityEnable).toBe(true); - await page.waitForTimeout(2000); }) - test('Test view yaml button', async ({ page }) => { - await page.waitForTimeout(7000); - securityPage.viewYaml() - await page.waitForTimeout(5000); + await securityPage.viewYaml() await expect(securityPage.editor_title_element).toBeTruthy(); - securityPage.closeButton() - await page.waitForTimeout(2000); + await securityPage.closeButton() }) - test('Test view and submit button', async ({ page }) => { - await page.waitForTimeout(5000); - securityPage.click_viewAndSubmitJob() - await page.waitForTimeout(5000); - await expect(securityPage.editor_title_element).toBeTruthy() - securityPage.closeButton() - await page.waitForTimeout(2000); - }) - test('Test view job', async ({ page }) => { - await page.waitForTimeout(5000); - securityPage.click_previewJob() - await page.waitForTimeout(5000); + test('Test view job output', async ({ page }) => { + await securityPage.click_viewAndSubmitJob() await expect(securityPage.editor_title_element).toBeTruthy() - securityPage.closeButton() - await page.waitForTimeout(5000); + await securityPage.closeButton() }) test('Test save and close and Resume Progress', async ({ page }) => { - await page.waitForTimeout(5000); - securityPage.fillSecurityDetails('RACF',SECURITY_ADMIN,SECURITY_STC,SECURITY_SYSPROG,SECURITY_USER_ZIS,SECURITY_USER_ZOWE,SECURITY_AUX,SECURITY_STC_ZOWE,SECURITY_STC_ZIS) - await page.waitForTimeout(5000); - securityPage.click_saveAndClose() - await page.waitForTimeout(3000); - titlePage.clickOnResumeProgress(); - await page.waitForTimeout(15000); + await securityPage.fillSecurityDetails('RACF', + config.SECURITY_ADMIN, + config.SECURITY_STC, + config.SECURITY_SYSPROG, + config.SECURITY_USER_ZIS, + config.SECURITY_USER_ZOWE, + config.SECURITY_AUX, + config.SECURITY_STC_ZOWE, + config.SECURITY_STC_ZIS + ) + await securityPage.click_saveAndClose() + await titlePage.clickOnResumeProgress(); + await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); + await connectionPage.SubmitValidateCredential(); const title = await securityPage.returnTitleOfSecurityPage(); expect(title).toBe(SECURITY_TITLE); const sysProg_value = await securityPage.get_sysProg_value(); diff --git a/playwright_test/utils/config.ts b/playwright_test/utils/config.ts new file mode 100644 index 00000000..2acdca11 --- /dev/null +++ b/playwright_test/utils/config.ts @@ -0,0 +1,72 @@ +interface Config { + SSH_HOST: string | undefined; + SSH_PASSWD: string | undefined; + SSH_PORT: string | undefined; + SSH_USER: string | undefined; + ZOWE_EXTENSION_DIR: string | undefined; + ZOWE_LOG_DIR: string | undefined; + ZOWE_ROOT_DIR: string | undefined; + ZOWE_WORKSPACE_DIR: string | undefined; + JOB_NAME: string | undefined; + JOB_PREFIX: string | undefined; + JAVA_HOME: string | undefined; + NODE_HOME: string | undefined; + ZOSMF_HOST: string | undefined; + ZOSMF_PORT: string | undefined; + ZOSMF_APP_ID: string | undefined; + DATASET_PREFIX: string | undefined; + AUTH_LOAD_LIB: string | undefined; + AUTH_PLUGIN_LIB: string | undefined; + PROC_LIB: string | undefined; + PARM_LIB: string | undefined; + JCL_LIB: string | undefined; + LOAD_LIB: string | undefined; + DOMAIN_NAME: string | undefined; + SECURITY_ADMIN: string | undefined; + EXTERNAL_PORT: number | undefined; + SECURITY_STC: string | undefined; + SECURITY_SYSPROG: string | undefined; + SECURITY_USER_ZIS: string | undefined; + SECURITY_USER_ZOWE: string | undefined; + SECURITY_AUX: string | undefined; + SECURITY_STC_ZOWE: string | undefined; + SECURITY_STC_ZIS: string | undefined; + +} + +const config: Config = { + SSH_HOST: process.env.SSH_HOST, + SSH_PASSWD: process.env.SSH_PASSWD, + SSH_PORT: process.env.SSH_PORT, + SSH_USER: process.env.SSH_USER, + ZOWE_EXTENSION_DIR: process.env.ZOWE_EXTENSION_DIR, + ZOWE_LOG_DIR: process.env.ZOWE_LOG_DIR, + ZOWE_ROOT_DIR: process.env.ZOWE_ROOT_DIR, + ZOWE_WORKSPACE_DIR: process.env.ZOWE_WORKSPACE_DIR, + JOB_NAME: process.env.JOB_NAME, + JOB_PREFIX: process.env.JOB_PREFIX, + JAVA_HOME: process.env.JAVA_HOME, + NODE_HOME: process.env.NODE_HOME, + ZOSMF_HOST: process.env.ZOSMF_HOST, + ZOSMF_PORT: process.env.ZOSMF_PORT, + ZOSMF_APP_ID: process.env.ZOSMF_APP_ID, + DATASET_PREFIX: process.env.DATASET_PREFIX, + AUTH_LOAD_LIB: process.env.AUTH_LOAD_LIB, + AUTH_PLUGIN_LIB: process.env.AUTH_PLUGIN_LIB, + PROC_LIB: process.env.PROC_LIB, + PARM_LIB: process.env.PARM_LIB, + JCL_LIB: process.env.JCL_LIB, + LOAD_LIB: process.env.LOAD_LIB, + EXTERNAL_PORT: process.env.EXTERNAL_PORT, + SECURITY_ADMIN: process.env.SECURITY_ADMIN, + SECURITY_STC: process.env.SECURITY_STC, + SECURITY_SYSPROG: process.env.SECURITY_SYSPROG, + SECURITY_USER_ZIS: process.env.SECURITY_USER_ZIS, + SECURITY_USER_ZOWE: process.env.SECURITY_USER_ZOWE, + SECURITY_AUX: process.env.SECURITY_AUX, + SECURITY_STC_ZOWE: process.env.SECURITY_STC_ZOWE, + SECURITY_STC_ZIS: process.env.SECURITY_STC_ZIS, + DOMAIN_NAME: process.env.DOMAIN_NAME +}; + +export default config; diff --git a/src/actions/InstallationHandler.ts b/src/actions/InstallationHandler.ts index 439638c4..67c8f710 100644 --- a/src/actions/InstallationHandler.ts +++ b/src/actions/InstallationHandler.ts @@ -19,16 +19,7 @@ import * as fs from 'fs'; import { ConfigurationStore } from '../storage/ConfigurationStore'; import { InstallationArgs } from '../types/stateInterfaces'; import { FALLBACK_SCHEMA, deepMerge } from '../renderer/components/common/Utils'; - - -//AJV did not like the regex in our current schema -const zoweDatasetMemberRegexFixed = { - "description": "PARMLIB member used by ZIS", - "type": "string", - "pattern": "^([A-Z$#@]){1}([A-Z0-9$#@]){0,7}$", - "minLength": 1, - "maxLength": 8 -} +import { updateSchemaReferences } from '../services/ResolveRef'; class Installation { @@ -152,19 +143,11 @@ class Installation { } //No reason not to always set schema to latest if user is re-running installation - if(readPaxYamlAndSchema.details.yamlSchema && readPaxYamlAndSchema.details.serverCommon){ + if(readPaxYamlAndSchema.details.schemas.yamlSchema){ try { - let yamlSchema = JSON.parse(readPaxYamlAndSchema.details.yamlSchema); - const serverCommon = JSON.parse(readPaxYamlAndSchema.details.serverCommon); - if(yamlSchema && serverCommon){ - yamlSchema.additionalProperties = true; - yamlSchema.properties.zowe.properties.setup.properties.dataset.properties.parmlibMembers.properties.zis = zoweDatasetMemberRegexFixed; - yamlSchema.properties.zowe.properties.setup.properties.certificate.properties.pkcs12.properties.directory = serverCommon.$defs.path; - if(yamlSchema.$defs?.networkSettings?.properties?.server?.properties?.listenAddresses?.items){ - delete yamlSchema.$defs?.networkSettings?.properties?.server?.properties?.listenAddresses?.items?.ref; - yamlSchema.$defs.networkSettings.properties.server.properties.listenAddresses.items = serverCommon.$defs.ipv4 - } - // console.log('Setting schema from runtime dir:', JSON.stringify(yamlSchema)); + let yamlSchema = JSON.parse(readPaxYamlAndSchema.details.schemas.yamlSchema); + updateSchemaReferences(readPaxYamlAndSchema.details.schemas, yamlSchema); + if(yamlSchema){ ConfigurationStore.setSchema(yamlSchema); parsedSchema = true; ProgressStore.set('downloadUnpax.getSchemas', true); @@ -266,11 +249,10 @@ class Installation { await this.getExampleYamlAndSchemas(connectionArgs, installationArgs).then((res: IResponse) => { if(res.status){ if(res.details.mergedYaml != undefined){ - yamlObj = res.details.mergedYaml + yamlObj = res.details.mergedYaml; } } }) - return {status: download.status && uploadYaml.status && upload.status && unpax.status, details: {message: 'Zowe unpax successful.', mergedYaml: yamlObj}}; } catch (error) { return {status: false, details: error.message}; @@ -630,10 +612,10 @@ export class FTPInstallation extends Installation { const yamlSchema = await new FileTransfer().download(connectionArgs, yamlSchemaPath, DataType.ASCII); const serverCommonPath = `${installDir}/schemas/server-common.json`; const serverCommon = await new FileTransfer().download(connectionArgs, serverCommonPath, DataType.ASCII); - return {status: true, details: {yaml, yamlSchema, serverCommon}}; + return {status: true, details: {yaml, schemas: {yamlSchema, serverCommon}}}; } catch (e) { console.log("Error downloading example-zowe.yaml and schemas:", e.message); - return {status: false, details: {yaml: '', yamlSchema: '', serverCommon: ''}} + return {status: false, details: {yaml: '', schemas: {yamlSchema: '', serverCommon: ''}}}; } } diff --git a/src/renderer/components/common/JsonForms.tsx b/src/renderer/components/common/JsonForms.tsx index dce65c2d..b6b65b6e 100644 --- a/src/renderer/components/common/JsonForms.tsx +++ b/src/renderer/components/common/JsonForms.tsx @@ -13,42 +13,141 @@ import { JsonForms } from '@jsonforms/react'; import { materialRenderers, materialCells } from '@jsonforms/material-renderers'; import { ThemeProvider } from '@mui/material/styles'; import jsonFormTheme from '../../jsonFormsTheme'; +import Radio from '@mui/material/Radio'; +import RadioGroup from '@mui/material/RadioGroup'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import FormControl from '@mui/material/FormControl'; + +// Creates a basic input element in the UI schema +const createControl = (scope: string, label?: string) => ({ + type: 'Control', + label: label ? label.charAt(0).toUpperCase() + label.slice(1).toLowerCase() : undefined, + scope, // Scope specifies the JSON path +}); + +// createGroup generates a group object, used to group together multiple form elements - can optionally include a rule (like visibility) +const createGroup = (label: string, elements: any[], rule?: any) => ({ + type: 'Group', + label: `\n${label}`, + elements: elements || [], + ...(rule && {rule}), +}); + +// createVerticalLayout generates a layout object that arranges its child elements vertically. +const createVerticalLayout = (elements: any[]) => ({ + type: 'VerticalLayout', + elements, +}); + +// Same as above, but arranges its child elements horizontally. +const createHorizontalLayout = (elements: any[]) => ({ + type: 'HorizontalLayout', + elements, +}); + +// To handle the "if", "else", and "then" in the schema +const conditionalSchema = (schema: any, formData: any, prop: any): boolean=> { + if(schema.if && schema.then && schema.else){ + const ifProp = Object.keys(schema.if.properties)[0]; + const ifPropValue = schema.if.properties[ifProp].const.toLowerCase(); + const thenProp = schema.then.required[0].toLowerCase(); + const elseProp = schema.else.required[0].toLowerCase(); + + if(formData && formData[ifProp]) { + const formDataPropValue = formData[ifProp].toLowerCase(); + if( (formDataPropValue == ifPropValue && prop == elseProp) || (formDataPropValue != ifPropValue && prop == thenProp) ) { + return true; + } + } + return false; + } + return false; +} + +const getDefaultFormData = (schema: any, formData: any) => { + if (schema.oneOf) { + schema = schema.oneOf[0]; + } + if (schema && schema.properties) { + const defaultFormData = { ...formData }; + Object.keys(schema.properties).forEach((property) => { + if (schema.properties[property].type && schema.properties[property].default !== undefined || schema.properties[property].type === 'object') { + // If the property is an object, recursively set default values + if (schema.properties[property].type === 'object') { + defaultFormData[property] = getDefaultFormData( + schema.properties[property], + defaultFormData[property] || {} + ); + } else { + defaultFormData[property] = schema.properties[property].default; + } + } + }); + return defaultFormData; + } + return null; +}; + +// Function to return form data based on the attributes present in the schema +const filterFormData = (data: { [key: string]: any }, schema: any) => { + if (!data) { + return null; + } + const filteredData: { [key: string]: any } = {}; + const schemaProperties = schema?.properties || {}; + + Object.keys(data).forEach(key => { + if (key in schemaProperties) { + filteredData[key] = data[key]; + } + }); + + return filteredData; +}; + +// Function to find the matching schema for the given form data +const findMatchingSchemaIndex = (formData: any, oneOfSchemas: any) => { + for (let i = 0; i < oneOfSchemas.length; i++) { + const subSchema = oneOfSchemas[i]; + const filteredData = filterFormData(formData, subSchema); + if (filteredData && JSON.stringify(filteredData) === JSON.stringify(formData)) { + return i; + } + } + return 0; // Default to the first schema if no match is found +}; const makeUISchema = (schema: any, base: string, formData: any): any => { if (!schema || !formData) { return ""; } + + if(schema.oneOf) { + const schemaIndex = findMatchingSchemaIndex(formData, schema.oneOf) + schema = schema.oneOf[schemaIndex]; + } + const properties = Object.keys(schema?.properties); - // Creates a basic input element in the UI schema - const createControl = (scope: string) => ({ - type: 'Control', - scope, // Scope specifies the JSON path - }); + // Map each property in the JSON schema to an appropriate UI element based on its type and structure. + const elements = properties.map((prop: any) => { - // createGroup generates a group object, used to group together multiple form elements - can optionally include a rule (like visibility) - const createGroup = (label: string, elements: any[], rule?: any) => ({ - type: 'Group', - label: `\n${label}`, - elements: elements || [], - ...(rule && {rule}), - }); + const propertySchema = schema.properties[prop]; - // createVerticalLayout generates a layout object that arranges its child elements vertically. - const createVerticalLayout = (elements: any[]) => ({ - type: 'VerticalLayout', - elements, - }); + if (propertySchema.anyOf && propertySchema.anyOf.length > 0) { + let matchingPropertyIndex = findMatchingSchemaIndex(formData[prop], propertySchema.anyOf); + let selectedProperty = propertySchema.anyOf[matchingPropertyIndex]; - // Same as above, but arranges its child elements horizontally. - const createHorizontalLayout = (elements: any[]) => ({ - type: 'HorizontalLayout', - elements, - }); + if (selectedProperty.type === 'null') { + matchingPropertyIndex = matchingPropertyIndex > 0 ? matchingPropertyIndex-1 : propertySchema.anyOf.length-1; + } - // Map each property in the JSON schema to an appropriate UI element based on its type and structure. - const elements = properties.map((prop: any) => { - if (schema.properties[prop].type === 'object') { + if (propertySchema.type !== 'object') { + return createControl(`#/properties${base}${prop}/anyOf[${matchingPropertyIndex}]`, prop); + } + } + + if (propertySchema.type === 'object') { // Create a group with a hide rule if patternProperties are present or conditional hiding is required. if (schema.properties[prop].patternProperties || (schema.if && conditionalSchema(schema, formData, prop))) { return createGroup(prop, [], { @@ -86,71 +185,63 @@ const makeUISchema = (schema: any, base: string, formData: any): any => { return createVerticalLayout(elements); // Return whole structure } -// To handle the "if", "else", and "then" in the schema -const conditionalSchema = (schema: any, formData: any, prop: any): boolean=> { - if(schema.if && schema.then && schema.else){ - const ifProp = Object.keys(schema.if.properties)[0]; - const ifPropValue = schema.if.properties[ifProp].const.toLowerCase(); - const thenProp = schema.then.required[0].toLowerCase(); - const elseProp = schema.else.required[0].toLowerCase(); - - if(formData && formData[ifProp]) { - const formDataPropValue = formData[ifProp].toLowerCase(); - if( (formDataPropValue == ifPropValue && prop == elseProp) || (formDataPropValue != ifPropValue && prop == thenProp) ) { - return true; - } - } - return false; - } - return false; -} - export default function JsonForm(props: any) { - const {schema, onChange, formData} = props; + let {schema, onChange, formData} = props; - const isFormDataEmpty = formData === null || formData === undefined; + const isFormDataEmpty = formData === null || formData === undefined || Object.keys(formData).length < 1; + formData = isFormDataEmpty ? getDefaultFormData(schema, {}) : formData; + + const [selectedSchemaIndex, setSelectedSchemaIndex] = schema.oneOf ? useState(findMatchingSchemaIndex(formData, schema.oneOf)) : useState(0); + const [requiredSchema, setRequiredSchema] = useState(schema); useEffect(() => { - if (isFormDataEmpty) { - const defaultFormData = getDefaultFormData(schema, formData); - onChange(defaultFormData); + if (schema?.oneOf) { + setRequiredSchema(schema.oneOf[selectedSchemaIndex]); + formData = filterFormData(formData, schema.oneOf[selectedSchemaIndex]); } - }, [isFormDataEmpty, schema, onChange]); - - const getDefaultFormData = (schema: any, formData: any) => { - if (schema && schema.properties) { - const defaultFormData = { ...formData }; - Object.keys(schema.properties).forEach((property) => { - if (schema.properties[property].type && schema.properties[property].default !== undefined || schema.properties[property].type === 'object') { - // If the property is an object, recursively set default values - if (schema.properties[property].type === 'object') { - defaultFormData[property] = getDefaultFormData( - schema.properties[property], - defaultFormData[property] || {} - ); - } else { - defaultFormData[property] = schema.properties[property].default; - } - } - }); - return defaultFormData; - } - return null; - }; - - // const [formState, setFormState] = useState(isFormDataEmpty ? getDefaultFormData(schema, {}) : formData); + }, []); + + const handleSchemaChange = (event: any) => { + const schemaIndex = parseInt(event.target.value); + setSelectedSchemaIndex(schemaIndex); + setRequiredSchema(schema.oneOf[schemaIndex]); + formData = filterFormData(formData, schema.oneOf[schemaIndex]); + onChange(formData, schemaIndex); + } return ( - { onChange(data) }} - /> + { schema.oneOf && +
+ + + { schema.oneOf.map((schemaOption: any, index: number) => ( + } + label={schemaOption.name ? schemaOption.name : `Option ${index+1}`} + /> + ))} + + +
+ + } + { schema.oneOf ? onChange(data, selectedSchemaIndex) : onChange(data) }} + />
); } \ No newline at end of file diff --git a/src/renderer/components/common/Stepper.tsx b/src/renderer/components/common/Stepper.tsx index 0b345870..382ce77c 100644 --- a/src/renderer/components/common/Stepper.tsx +++ b/src/renderer/components/common/Stepper.tsx @@ -28,8 +28,7 @@ import eventDispatcher from '../../../services/eventDispatcher'; import Warning from '@mui/icons-material/Warning'; import CheckCircle from '@mui/icons-material/CheckCircle'; import { TYPE_YAML, TYPE_OUTPUT, TYPE_JCL, INIT_STAGE_LABEL, REVIEW_INSTALL_STAGE_LABEL, UNPAX_STAGE_LABEL } from '../common/Utils'; -import { getProgress, getCompleteProgress, mapAndSetSkipStatus, mapAndGetSkipStatus } from '../stages/progress/StageProgressStatus'; - +import { getProgress, getCompleteProgress, updateSubStepSkipStatus, updateStepSkipStatus } from '../stages/progress/StageProgressStatus'; import '../../styles/Stepper.css'; import { StepIcon } from '@mui/material'; import { getStageDetails } from '../../../services/StageDetails'; @@ -57,7 +56,7 @@ export default function HorizontalLinearStepper({stages, initialization}:{stages completeProgress.reviewStatus ]; - const [subStageProgressStatus, setProgressStatus] = useState([ + const [subStageProgressStatus, setSubStageProgressStatus] = useState([ completeProgress.datasetInstallationStatus, completeProgress.networkingStatus, completeProgress.apfAuthStatus, @@ -67,8 +66,6 @@ export default function HorizontalLinearStepper({stages, initialization}:{stages completeProgress.launchConfigStatus ]) - - const [activeStep, setActiveStep] = initialization ? useState(0) : useState(useAppSelector(selectActiveStepIndex)); const [activeSubStep, setActiveSubStep] = initialization ? useState(0) : useState(useAppSelector(selectActiveSubStepIndex)); const [nextText, setNextText] = useState("Continue"); @@ -80,18 +77,9 @@ export default function HorizontalLinearStepper({stages, initialization}:{stages const dispatch = useAppDispatch(); useEffect(() => { - const mvsCompleteListener = (completed: boolean) => { - setProgressStatus([true, completeProgress.networkingStatus, - completeProgress.apfAuthStatus, - completeProgress.securityStatus, - completeProgress.certificateStatus, - completeProgress.launchConfigStatus]) - }; eventDispatcher.on('updateActiveStep', updateActiveStepListener); - eventDispatcher.on('initMvsComplete', mvsCompleteListener); return () => { eventDispatcher.off('updateActiveStep', updateActiveStepListener); - eventDispatcher.off('initMvsComplete', mvsCompleteListener); }; }, []); @@ -129,9 +117,10 @@ export default function HorizontalLinearStepper({stages, initialization}:{stages const handleSkip = async () => { stages[activeStep].isSkipped = true; + updateStepSkipStatus(activeStep, true); if(stages[activeStep].subStages){ stages[activeStep].subStages[activeSubStep].isSkipped = true; - mapAndSetSkipStatus(activeSubStep, true); + updateSubStepSkipStatus(activeSubStep, true); } if(stages[activeStep].label === UNPAX_STAGE_LABEL && installationArgs.installationType != "smpe"){ alertEmitter.emit('showAlert', 'Retrieving example-zowe.yaml and latest schemas from Zowe runtime files...', 'info'); @@ -200,13 +189,13 @@ export default function HorizontalLinearStepper({stages, initialization}:{stages } } - const getStepIcon = (error: any, stageId: number, isSubStep?: boolean, subStepId?: number) => { + const getStepIcon = (stageId: number, isSubStep?: boolean, subStepId?: number) => { - if (!error || (isSubStep && getProgress(stages[stageId].subStages[subStepId].statusKey)) || (!isSubStep && getProgress(stages[stageId].statusKey))) { + if ((isSubStep && getProgress(stages[stageId].subStages[subStepId].statusKey)) || (!isSubStep && ((stageId == 0 && connectionStatus) || (getProgress(stages[stageId].statusKey))))) { return } />; } - if ((isSubStep && mapAndGetSkipStatus(subStepId)) || (error && activeStep>stageId && !isSubStep) || (error && isSubStep && stages[stageId].subStages[subStepId].isSkipped)) { + if ((isSubStep && stages[stageId].subStages[subStepId].isSkipped) || (!isSubStep && stages[stageId].isSkipped)) { return } />; } @@ -295,9 +284,7 @@ export default function HorizontalLinearStepper({stages, initialization}:{stages borderTopLeftRadius: '7px', boxShadow: 'rgb(0 0 0 / 15%) 0px 6px 4px -1px inset'} : {}}> : }> - icon={getStepIcon(labelProps.error, stage.id)}> + icon={getStepIcon(stage.id)}> handleStepperClick(stage.id, !!stage.subStage)}>{stage.label} @@ -314,9 +301,7 @@ export default function HorizontalLinearStepper({stages, initialization}:{stages return ( : }> - icon={getStepIcon(labelProps.error, activeStep, true, index)}> + icon={getStepIcon(activeStep, true, index)}> handleStepperClick(activeStep, true, stage.id )}>{stage.label} diff --git a/src/renderer/components/stages/Certificates.tsx b/src/renderer/components/stages/Certificates.tsx index 1ea19536..b02b6c39 100644 --- a/src/renderer/components/stages/Certificates.tsx +++ b/src/renderer/components/stages/Certificates.tsx @@ -8,7 +8,7 @@ * Copyright Contributors to the Zowe Project. */ -import { useState, useEffect } from "react"; +import { useState, useEffect, useRef } from "react"; import { Box, Button, FormControl, FormHelperText, MenuItem, Select } from '@mui/material'; import { useAppSelector, useAppDispatch } from '../../hooks'; import { setInitializationStatus, setCertificateStatus } from './progress/progressSlice'; @@ -24,7 +24,7 @@ import { createTheme } from '@mui/material/styles'; import { stages } from "../configuration-wizard/Wizard"; import { setActiveStep } from "./progress/activeStepSlice"; import { getStageDetails, getSubStageDetails } from "../../../services/StageDetails"; -import { getProgress, setCertificateInitState, getCertificateInitState, mapAndSetSkipStatus, getInstallationArguments, isInitComplete } from "./progress/StageProgressStatus"; +import { getProgress, setCertificateInitState, getCertificateInitState, updateSubStepSkipStatus, getInstallationArguments, isInitializationStageComplete } from "./progress/StageProgressStatus"; import { CertInitSubStepsState } from "../../../types/stateInterfaces"; import { TYPE_YAML, TYPE_OUTPUT, INIT_STAGE_LABEL, CERTIFICATES_STAGE_LABEL, ajv, deepMerge } from "../common/Utils"; @@ -38,11 +38,11 @@ const Certificates = () => { const dispatch = useAppDispatch(); const [schema, setLocalSchema] = useState(useAppSelector(selectSchema)); - const [yaml, setLocalYaml] = useState(useAppSelector(selectYaml)); + const yaml = useAppSelector(selectYaml); const [connectionArgs] = useState(useAppSelector(selectConnectionArgs)); const [installationArgs] = useState(getInstallationArguments()); const [setupSchema] = useState(schema?.properties?.zowe?.properties?.setup?.properties?.certificate); - const [setupYaml, setSetupYaml] = useState(yaml?.zowe?.setup?.certificate); + const setupYaml = yaml?.zowe?.setup?.certificate; const [verifyCerts, setVerifyCerts] = useState(yaml?.zowe?.verifyCertificates ?? "STRICT"); const [isFormInit, setIsFormInit] = useState(false); const [editorVisible, setEditorVisible] = useState(false); @@ -54,14 +54,24 @@ const Certificates = () => { const [stateUpdated, setStateUpdated] = useState(false); const [initClicked, setInitClicked] = useState(false); const [reinit, setReinit] = useState(false); + const [stageStatus, setStageStatus] = useState(stages[STAGE_ID].subStages[SUB_STAGE_ID].isSkipped); + const stageStatusRef = useRef(stageStatus); let timer: any; const [validate] = useState(() => ajv.getSchema("https://zowe.org/schemas/v2/server-base") || ajv.compile(setupSchema)) useEffect(() => { - dispatch(setInitializationStatus(isInitComplete())); - if(getProgress('certificateStatus')) { + stageStatusRef.current = stageStatus; + }, [stageStatus]); + + useEffect(() => { + const stepProgress = getProgress('certificateStatus'); + + dispatch(setInitializationStatus(isInitializationStageComplete())); + setShowProgress(initClicked || stepProgress); + + if(stepProgress) { const nextPosition = document.getElementById('start-certificate-progress'); nextPosition.scrollIntoView({ behavior: 'smooth', block: 'start' }); } else { @@ -69,11 +79,12 @@ const Certificates = () => { nextPosition.scrollIntoView({behavior: 'smooth'}); } - setShowProgress(initClicked || getProgress('certificateStatus')); - updateProgress(getProgress('certificateStatus')); + dispatch(setNextStepEnabled(stepProgress)); + setIsFormInit(true); return () => { + updateSubStepSkipStatus(SUB_STAGE_ID, stageStatusRef.current); dispatch(setActiveStep({ activeStepIndex: STAGE_ID, isSubStep: SUB_STAGES, activeSubStepIndex: SUB_STAGE_ID })); } }, []); @@ -84,6 +95,8 @@ const Certificates = () => { if(initClicked) { let nextPosition = document.getElementById('start-certificate-progress'); nextPosition?.scrollIntoView({ behavior: 'smooth', block: 'start' }); + dispatchActions(false); + setStateUpdated(!stateUpdated); } }, [initClicked]); @@ -92,7 +105,10 @@ const Certificates = () => { if(!getProgress('certificateStatus') && initClicked) { timer = setInterval(() => { window.electron.ipcRenderer.getCertificateProgress().then((res: any) => { - setCertificateInitializationProgress(res) + setCertificateInitializationProgress(res); + if(res.success){ + clearInterval(timer); + } }) }, 3000); } @@ -110,8 +126,7 @@ const Certificates = () => { useEffect(() => { const allAttributesTrue = Object.values(certificateInitProgress).every(value => value === true); if(allAttributesTrue) { - dispatch(setNextStepEnabled(true)); - dispatch(setCertificateStatus(true)); + dispatchActions(true); setShowProgress(initClicked || getProgress('certificateStatus')); } }, [certificateInitProgress]); @@ -121,21 +136,18 @@ const Certificates = () => { setCertificateInitState(certificateInitState); const allAttributesTrue = Object.values(certificateInitState).every(value => value === true); if(allAttributesTrue) { - dispatch(setNextStepEnabled(true)); - dispatch(setCertificateStatus(true)); + dispatchActions(true); } } const setStageSkipStatus = (status: boolean) => { stages[STAGE_ID].subStages[SUB_STAGE_ID].isSkipped = status; - stages[STAGE_ID].isSkipped = status; - mapAndSetSkipStatus(SUB_STAGE_ID, status); + stages[STAGE_ID].isSkipped = !isInitializationStageComplete(); + setStageStatus(status); } const updateProgress = (status: boolean) => { setStateUpdated(!stateUpdated); - setStageSkipStatus(!status); - if(!status) { for (let key in certificateInitProgress) { certificateInitProgress[key as keyof(CertInitSubStepsState)] = false; @@ -144,10 +156,15 @@ const Certificates = () => { } const allAttributesTrue = Object.values(certificateInitProgress).every(value => value === true); status = allAttributesTrue ? true : false; - dispatch(setNextStepEnabled(status)); - dispatch(setInitializationStatus(isInitComplete())); - dispatch(setCertificateStatus(status)); setCertificateInitializationProgress(getCertificateInitState()); + dispatchActions(status); + } + + const dispatchActions = (status: boolean) => { + dispatch(setCertificateStatus(status)); + dispatch(setInitializationStatus(isInitializationStageComplete())); + dispatch(setNextStepEnabled(status)); + setStageSkipStatus(!status); } const reinitialize = (event: any) => { @@ -171,7 +188,6 @@ const Certificates = () => { if(res.details.updatedYaml != undefined){ const updatedCerts = res.details.updatedYaml.zowe?.certificate; const updatedYaml = {...yaml, zowe: {...yaml.zowe, certificate: updatedCerts}}; - setSetupYaml(res.details.updatedYaml.zowe?.setup.certificate); window.electron.ipcRenderer.setConfig(updatedYaml); dispatch(setYaml(updatedYaml)); } @@ -201,7 +217,7 @@ const Certificates = () => { setEditorVisible(!editorVisible); }; - const handleFormChange = (data: any) => { + const handleFormChange = (data: any, schemaOption?: any) => { if(data?.zowe?.verifyCertificates){ setVerifyCerts(data.zowe.verifyCertificates); } @@ -209,28 +225,36 @@ const Certificates = () => { setIsFormInit(false); if (newData) { - dispatch(setCertificateStatus(false)); - if(validate) { validate(newData); + if(validate.errors) { - const errPath = validate.errors[0].schemaPath; - const errMsg = validate.errors[0].message; - setStageConfig(false, errPath+' '+errMsg, newData); + const { schemaPath, message } = validate.errors[0]; + let errorText = `${schemaPath} ${message}`; + + if(schemaOption !== undefined && schemaOption !== null) { + validate.errors.forEach(err => { + if (err.schemaPath.includes(schemaOption)) { + errorText = err.message; + } + }) + } + + setStageConfig(false, errorText, newData); } else { - window.electron.ipcRenderer.setConfig({...yaml, zowe: {...yaml.zowe, setup: {...yaml.zowe.setup, certificate: newData}}}); - setLocalYaml({...yaml, zowe: {...yaml.zowe, setup: {...yaml.zowe.setup, certificate: newData}}}); setStageConfig(true, '', newData); } + + const updatedYaml = {...yaml, zowe: {...yaml.zowe, setup: {...yaml.zowe.setup, certificate: newData}}}; + window.electron.ipcRenderer.setConfig(updatedYaml); + dispatch(setYaml(updatedYaml)); } } }; - const setStageConfig = (isValid: boolean, errorMsg: string, data: any) => { setIsFormValid(isValid); setFormError(errorMsg); - setSetupYaml(data); } return ( @@ -249,10 +273,9 @@ const Certificates = () => { setStageConfig(true, '', newData); } }/> } - dispatch(setYaml((await window.electron.ipcRenderer.getConfig()).details ?? yaml))}> + {!isFormValid &&
{formError}
} - - {/* */} +

Verify Certificates