diff --git a/package-lock.json b/package-lock.json index 5c50ff45..ae934625 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "electron-store": "^8.1.0", "flat": "^5.0.2", "js-yaml": "^4.1.0", + "node-ssh": "^13.2.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-redux": "^8.0.5", @@ -3113,6 +3114,15 @@ "node": ">= 6" } }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -3226,6 +3236,15 @@ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", "dev": true }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -3441,6 +3460,15 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "node_modules/buildcheck": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.6.tgz", + "integrity": "sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==", + "optional": true, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -4047,6 +4075,20 @@ "node": ">= 6" } }, + "node_modules/cpu-features": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz", + "integrity": "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "buildcheck": "~0.0.6", + "nan": "^2.19.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -8335,6 +8377,30 @@ "nan": "^2.4.0" } }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -8712,7 +8778,6 @@ "version": "2.19.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.19.0.tgz", "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==", - "dev": true, "optional": true }, "node_modules/nanoid": { @@ -8882,6 +8947,35 @@ "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, + "node_modules/node-ssh": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/node-ssh/-/node-ssh-13.2.0.tgz", + "integrity": "sha512-7vsKR2Bbs66th6IWCy/7SN4MSwlVt+G6QrHB631BjRUM8/LmvDugtYhi0uAmgvHS/+PVurfNBOmELf30rm0MZg==", + "license": "MIT", + "dependencies": { + "is-stream": "^2.0.0", + "make-dir": "^3.1.0", + "sb-promise-queue": "^2.1.0", + "sb-scandir": "^3.1.0", + "shell-escape": "^0.2.0", + "ssh2": "^1.14.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/node-ssh/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/nopt": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", @@ -10617,8 +10711,28 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sb-promise-queue": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sb-promise-queue/-/sb-promise-queue-2.1.0.tgz", + "integrity": "sha512-zwq4YuP1FQFkGx2Q7GIkZYZ6PqWpV+bg0nIO1sJhWOyGyhqbj0MsTvK6lCFo5TQwX5pZr6SCQ75e8PCDCuNvkg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/sb-scandir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/sb-scandir/-/sb-scandir-3.1.0.tgz", + "integrity": "sha512-70BVm2xz9jn94zSQdpvYrEG101/UV9TVGcfWr9T5iob3QhCK4lYXeculfBqPGFv3XTeKgx4dpWyYIDeZUqo4kg==", + "license": "MIT", + "dependencies": { + "sb-promise-queue": "^2.1.0" + }, + "engines": { + "node": ">= 8" + } }, "node_modules/scheduler": { "version": "0.23.2", @@ -10967,6 +11081,12 @@ "node": ">=8" } }, + "node_modules/shell-escape": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/shell-escape/-/shell-escape-0.2.0.tgz", + "integrity": "sha512-uRRBT2MfEOyxuECseCZd28jC1AJ8hmqqneWQ4VWUTgCAFvb3wKU1jLqj6egC4Exrr88ogg3dp+zroH4wJuaXzw==", + "license": "MIT" + }, "node_modules/shell-quote": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", @@ -11176,6 +11296,23 @@ "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", "dev": true }, + "node_modules/ssh2": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.15.0.tgz", + "integrity": "sha512-C0PHgX4h6lBxYx7hcXwu3QWdh4tg6tZZsTfXcdvc5caW/EMxaB4H9dWsl7qk+F7LAW762hp8VbXOX7x4xUYvEw==", + "hasInstallScript": true, + "dependencies": { + "asn1": "^0.2.6", + "bcrypt-pbkdf": "^1.0.2" + }, + "engines": { + "node": ">=10.16.0" + }, + "optionalDependencies": { + "cpu-features": "~0.0.9", + "nan": "^2.18.0" + } + }, "node_modules/ssri": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", @@ -11791,6 +11928,12 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "license": "Unlicense" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/package.json b/package.json index 86e49446..4da02571 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,7 @@ "electron-store": "^8.1.0", "flat": "^5.0.2", "js-yaml": "^4.1.0", + "node-ssh": "^13.2.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-redux": "^8.0.5", diff --git a/playwright_test/Pages/apfAuth.page.ts b/playwright_test/Pages/apfAuth.page.ts index 953ad80f..224d2021 100644 --- a/playwright_test/Pages/apfAuth.page.ts +++ b/playwright_test/Pages/apfAuth.page.ts @@ -53,24 +53,26 @@ class ApfAuthPage{ this.pageTitle = page.locator("//div[@class='MuiBox-root css-la96ob']/div") this.continueButtonSelector = page.locator('.MuiButton-containedPrimary.MuiButton-sizeMedium') this.userNameInputSelector = page.locator('label:has-text("User Name") + div input#standard-required') - this.writeConfig_greenCheckXpath = page.locator('#card-download-progress-card svg.MuiSvgIcon-colorSuccess') - this.uploadYaml_greenCheckXpath = page.locator('#card-download-progress-card svg.MuiSvgIcon-colorSuccess') - this.init_apfauth_greenCheckXpath = page.locator("#card-upload-progress-card svg.MuiSvgIcon-colorSuccess") + this.writeConfig_greenCheckXpath = page.locator('//*[@id="box-download-progress-card"][1]') + this.uploadYaml_greenCheckXpath = page.locator('//*[@id="box-download-progress-card"][2]') + this.init_apfauth_greenCheckXpath = page.locator('//*[@id="card-upload-progress-card"]') this.previous_step_button = page.locator('//button[contains(text(),"Previous step")]') this.skip_installation_button = page.locator('//button[contains(text(),"Skip")]') this.skip_apf_auth_button = page.locator('//button[contains(text(),"Skip")]') this.continue_apfauth_setup = page.locator('//button[contains(text(),"Continue to APF Auth Setup")]') this.continue_security_setup = page.locator('//button[contains(text(),"Continue to Security Setup")]') this.editor_title_element = page.locator('//h2[text()="Editor"]') - this.APFAUTH_TITLE = page.locator('APF Authorize Load Libraries') + this.APFAUTH_TITLE = page.locator('//*[@id="container-box-id"]/form/div/div[1]/div') this.installationTitle = page.locator('//div[text()="Installation"]') + 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.datasetPrefix = page.getByLabel('Prefix') - this.authLoadLib = page.getByLabel('Auth Loadlib') - this.authpluginLib = page.getByLabel('Auth Plugin Lib') - this.click_ApfAuth = page.locator('//span[text()="Apf Auth"]'); + this.datasetPrefix = page.locator("//label[text()='Prefix']//following-sibling::div/input") + this.authLoadLib = page.locator("//label[text()='Auth Loadlib']//following-sibling::div/input") + this.authpluginLib = page.locator("//label[text()='Auth Plugin Lib']//following-sibling::div/input") + this.click_ApfAuth = page.locator('//span[text()="APF Auth"]'); + this.click_Installation = page.locator('//span[text()="Installation"]') this.skipInstallation = page.locator('//button[contains(text(),"Skip")]') this.run_zwe_init_apfauth = page.locator('//button[contains(text(),"zwe init apfauth")]') this.view_yaml = page.locator('//button[contains(text(),"View/Edit Yaml")]') @@ -79,7 +81,7 @@ class ApfAuthPage{ this.save_and_close = page.locator('//button[contains(text(),"Save & close")]') this.previous_step = page.locator('//button[contains(text(),"Previous step")]') this.skip_apf_auth = page.locator('//button[contains(text(),"Skip")]') - this.initApfauth = page.locator('//button[contains(text(),"zwe init apfauth")]') + this.initApfauth = page.locator('//button[contains(text(),"Initialize APF Authorizations")]') this.close_button = page.locator('//button[contains(text(), "Close")]') this.securityTab_title = page.locator('//div[text()="Security"]') this.dataset_prefix_value = page.getByLabel('Dataset Prefix') @@ -95,6 +97,7 @@ class ApfAuthPage{ } async movetoApfAuthPage(){ + await this.page.waitForTimeout(500) await this.click_ApfAuth.click({timeout: 9000}) } @@ -111,12 +114,31 @@ class ApfAuthPage{ } async fillApfDetails(datasetPrefix:string, authLoadLib:string,authpluginLib:string){ - await this.datasetPrefix.fill(datasetPrefix,{ timeout: 10000 }) - await this.authLoadLib.fill(authLoadLib,{ timeout: 10000 }) - await this.authpluginLib.fill(authpluginLib,{ timeout: 10000 }) + await this.page.waitForTimeout(500) + await this.datasetPrefix.fill(datasetPrefix); + await this.page.waitForTimeout(500) + await this.authLoadLib.fill(authLoadLib); + await this.authpluginLib.fill(authpluginLib); + await this.page.waitForTimeout(5000) + } async initializeApfauth(){ await this.initApfauth.click() + await this.waitForContinueButtonToBeEnabled(); + } + + private async waitForContinueButtonToBeEnabled(): Promise { + const timeout = 1000000; + const interval = 500; + const endTime = Date.now() + timeout; + while (Date.now() < endTime) { + if (await this.isContinueButtonEnabled()) { + return; + } + await this.page.waitForTimeout(interval); + } + + throw new Error('Continue button was not enabled within the timeout period'); } async isWriteConfigGreenCheckVisible(){ return await this.writeConfig_greenCheckXpath.isVisible({ timeout: 50000 }); @@ -133,8 +155,8 @@ class ApfAuthPage{ async returnTitleOfPrevPage(){ await this.previous_step_button.click({ timeout: 2000 }); - const installation_title = await this.installationTitle.textContent(); - return installation_title; + const networking_title = await this.NETWORKING_TITLE.textContent(); + return networking_title; } async viewYaml(){ await this.view_yaml.click({ timeout: 2000 }) @@ -186,4 +208,4 @@ class ApfAuthPage{ } - export default ApfAuthPage; \ No newline at end of file + export default ApfAuthPage; diff --git a/playwright_test/Pages/connection.page.ts b/playwright_test/Pages/connection.page.ts index 1b1f5324..a9d37b41 100644 --- a/playwright_test/Pages/connection.page.ts +++ b/playwright_test/Pages/connection.page.ts @@ -64,14 +64,15 @@ class ConnectionPage{ async SubmitValidateCredential(){ console.log("Submitting credentials..."); - await this.page.waitForTimeout(1000); await this.validateCredential.click(); + await this.page.waitForTimeout(5000); console.log("Credentials submitted."); } async clickContinueButton() { await this.page.waitForTimeout(1000); - return await this.continueButton.click(); + await this.continueButton.click(); + } async click_saveAndClose(){ @@ -80,9 +81,10 @@ class ConnectionPage{ async isContinueButtonVisible() { return await this.continueButton.isDisabled(); } + async isGreenCheckIconVisible() { return await this.greenCheckIconSelector.isHidden(); } } -export default ConnectionPage; \ No newline at end of file +export default ConnectionPage; diff --git a/playwright_test/Pages/installation.page.ts b/playwright_test/Pages/installation.page.ts index ee8a1753..ec6bc3ea 100644 --- a/playwright_test/Pages/installation.page.ts +++ b/playwright_test/Pages/installation.page.ts @@ -21,6 +21,7 @@ class InstallationPage{ continueToNetworkSetup: Locator; editorTitleElement: Locator; closeEditorButton: Locator; + ErrorMsg: Locator; constructor(page: Page) { this.page = page; @@ -37,12 +38,13 @@ class InstallationPage{ this.viewEditYaml = page.locator("//button[text()='View/Edit Yaml']") this.viewSubmitJob = page.locator("//button[text()='View/Submit Job']") this.viewJobOutput = page.locator("//button[text()='View Job Output']") - this.saveAndClose = page.locator("//button[text()='Save & close']") + this.saveAndClose = page.locator("//button[text()='Save & close']") this.previousStep = page.locator("//button[text()='Previous step']") this.skipInstallation = page.locator("//button[contains(text(),'Skip')]") this.continueToNetworkSetup = page.locator("//button[text()='Continue to Network Setup']") this.editorTitleElement = page.locator("//h2[text()='Editor']") this.closeEditorButton = page.locator("//button[text()='Close']") + this.ErrorMsg = page.locator('//*[@id="zen-root-container"]/div[1]/header/div/div[2]') } async getInstallationPageTitle(){ @@ -50,8 +52,13 @@ class InstallationPage{ return await this.pageTitle.textContent({ timeout: 2000 }); } + async getErrorMsg(){ + await this.page.waitForTimeout(2000) + return await this.ErrorMsg.textContent({ timeout: 2000 }); + } + async enterPrefix(prefix: string): Promise{ - await this.page.waitForTimeout(500) + await this.page.waitForTimeout(1000) await this.prefix.fill(prefix); } @@ -188,6 +195,7 @@ class InstallationPage{ async clickInstallMvsDatasetsInvalid(){ await this.installMVSDatasets.click(); + await this.page.waitForTimeout(500) } async fillAllFields(datasetPrefix: string, parmLib: string, procLib: string, jclLib: string, loadLib: string, authLoadLib: string, authPluginLib: string){ @@ -198,10 +206,6 @@ class InstallationPage{ 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 b7730c22..010a8335 100644 --- a/playwright_test/Pages/installationType.page.ts +++ b/playwright_test/Pages/installationType.page.ts @@ -21,12 +21,13 @@ class InstallationTypePage{ constructor(page: Page) { this.page = page; + this.installationPageTitle = page.locator("//div[text()='Installation']") this.pageTitle = page.locator("//div[@class='MuiBox-root css-la96ob']/div") this.downloadPax = page.locator("//span[text()='Download Zowe convenience build PAX from internet']/preceding-sibling::span/input") 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,10 +37,13 @@ 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 ']") + 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 ']") + this.continueToUnpax = page.locator("//button[contains(text(),'Continue to Unpax')]") + this.SkipUnpax = page.locator('//button[contains(text(),"Skip")]') + this.retrieveExampleZoweYaml= page.locator('//button[contains(text(),"Retrieve example-zowe.yaml")]') + this.click_InitializationStage = page.locator('//span[text()="Initialization"]') } async getInstallationTypePageTitle(){ @@ -57,15 +61,15 @@ class InstallationTypePage{ async selectSmpe(){ await this.smpe.click({timeout: 5000}); } - + async continueToUnpax(){ - await this.continueUpnax.click({timeout: 5000}); + await this.continueToUnpax.click({ timeout: 2000 }) } - + async retrieveExampleYaml(){ await this.retrieveExampleZoweYaml.click({timeout: 5000}); } - + async continueComponentInstallation(){ const timeout = 5000; const interval = 500; @@ -79,6 +83,20 @@ class InstallationTypePage{ await this.continueCompInstallation.click({timeout: timeout}); } + private async waitForInstallationPageVisible(): Promise { + const timeout = 1000000; + const interval = 500; + const endTime = Date.now() + timeout; + while (Date.now() < endTime) { + if (await this.installationPageTitle.isVisible()) { + return; + } + await this.page.waitForTimeout(interval); + } + + throw new Error('Timed out waiting for the Installation Page to become visible.'); + } + async clickZoweLink(){ await this.zoweLink.click(); } @@ -106,9 +124,9 @@ class InstallationTypePage{ async isContinueToComponentInstallationEnabled(){ return await this.continueToComponentInstallation.isEnabled() } - + async isContinueUnpaxEnabled(){ - return await this.continueUpnax.isEnabled() + return await this.continueToUnpax.isEnabled() } async clickAgreeLicense(){ @@ -116,15 +134,18 @@ class InstallationTypePage{ } async isLicenseAgreementGreenCheckVisible(){ - return await this.licenseAgreementGreenCheck.isVisible(); + await this.page.waitForTimeout(5000); + return await this.licenseAgreementGreenCheck.isVisible({timeout: 5000}); } async clickUploadPaxButton(){ await this.uploadPaxButton.click({timeout: 5000}); } - + async skipUnpax(){ await this.skipUnpaxButton.click({timeout: 5000}); + await this.waitForInstallationPageVisible(); + } async enterRuntimeDir(runtimeDir: any){ @@ -141,20 +162,35 @@ class InstallationTypePage{ } async downloadZowePaxAndNavigateToInstallationPage(){ - this.selectDownloadZowePax() - this.clickLicenseAgreement() - this.clickAgreeLicense() - } + await this.selectDownloadZowePax() + await this.clickLicenseAgreement() + await this.clickAgreeLicense() + } async uploadZowePaxAndNavigateToInstallationPage(uploadPaxPath: any){ this.selectUploadZowePax() await this.uploadPaxButton.setInputFiles(uploadPaxPath) - } + } async smpeZowePaxAndNavigateToInstallationPage(runtimeDir: any){ this.selectSmpe() this.enterRuntimeDir(runtimeDir) this.clickValidateLocation() - } + } + async clickOnContinueToUnpax(){ + this.continueToUnpax.click({ timeout: 2000 }) + } + + async clickSkipUnpaxButton(){ + this.SkipUnpax.click({ timeout: 2000 }) + } + + async clickRetrieveExZoweYaml(){ + this.retrieveExampleZoweYaml.click({ timeout: 15000 }) + } + + async MoveToInitializationStage(){ + this.click_InitializationStage.click({ timeout: 15000 }) + } } export default InstallationTypePage; diff --git a/playwright_test/Pages/launchConfig.page.ts b/playwright_test/Pages/launchConfig.page.ts index 64dce7f2..fe7bebab 100644 --- a/playwright_test/Pages/launchConfig.page.ts +++ b/playwright_test/Pages/launchConfig.page.ts @@ -16,7 +16,7 @@ class LaunchConfigPage{ skip_button:Locator; view_yaml:Locator; view_submit_job:Locator; - view_job_output:Locator; + viewJobOutput:Locator; save_and_close:Locator; previous_step:Locator; close_button:Locator; @@ -29,44 +29,45 @@ class LaunchConfigPage{ this.page = page; this.pageTitle = page.locator("//div[@class='MuiBox-root css-la96ob']/div") this.click_launchConfig = page.locator('//span[text()="Launch Config"]') + this.reviewPage_title = page.locator('//span[text()="Review Installation"]') this.validation = page.getByLabel('Validation'); this.logLevel = page.getByLabel('LogLevel'); this.componentConfig = page.getByLabel('On Component Configure Fail'); - this.fillValidation = page.locator('input[id="#/properties/configmgr/properties/validation2"]') + this.fillValidation = page.getByLabel('Validation'); + this.clearText = page.locator('//input[@id="#/properties/configmgr/properties/validation4"]/following-sibling::div//button[@aria-label="Clear"]') this.readYaml = page.locator('div.view-lines') this.fillConfigLaunchValue = page.locator('//html/body/div/div[2]/div/div[4]/div/form/div/div[2]/div/div[2]/div/div[2]/div/div/div/div/div/div[2]/div/div/div/input') this.fillLogLevel = page.locator('//html/body/div/div[2]/div/div[4]/div/form/div/div[2]/div/div[2]/div/div[2]/div/div/div/div/div/div[1]/div/div/div/input') 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.CONFPAGE_TITLE = page.locator(' //div[text()="Configuration"]') + this.CONFPAGE_TITLE = page.locator('//div[text()="Configuration"]') 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.viewAndSubmitJob = page.locator('//button[contains(text(), "Preview Job")]') - this.view_job_output = page.locator('//button[contains(text(), "Submit Job")]') + this.view_yaml = page.locator('//button[contains(text(),"View/Edit Yaml")]') + this.viewJobOutput = page.locator('//button[contains(text(), "View Job Output")]') 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.certificateTab_title = page.locator('//div[text()="Certificates"]') + this.cachingService_title = page.locator('//div[text()="CachingService"]') this.continue_ReviewSelector = page.locator('//button[contains(text(), "Review")]') this.errorMsg = page.locator('//p[text()="is a required property"]') } async movetoLaunchConfigPage(){ - await this.licenseAgreement.click({timeout: 9000}) - await this.acceptLicense.click({timeout: 9000}) - await this.continueToComponentInstallation.click({timeout: 5000}) await this.click_launchConfig.click({timeout: 5000}) } async getLaunchConfigurationPageTitle() { return await this.pageTitle.textContent({ timeout: 2000 }); } async fillvalues(validation:string){ - await this.page.fill('input[id="#/properties/configmgr/properties/validation"]', validation, { timeout: 10000 }); + const inputLocator = this.page.locator('//html/body/div/div[2]/div/div[4]/div/form/div/div[2]/div/div[1]/div/div[2]/div/div/div/div/div/div/div/div/div/input'); + await inputLocator.fill(validation); + await inputLocator.press('Enter'); } + async fillvalues_logLevel(logLevel:string){ await this.fillLogLevel.fill(logLevel,{ timeout: 10000 }) } @@ -102,13 +103,13 @@ class LaunchConfigPage{ await this.view_yaml.click({ timeout: 5000 }) } async closeButton(){ - this.close_button.click({ timeout: 2000 }) + await this.close_button.click({ timeout: 2000 }) } - async click_viewAndSubmitJob(){ - this.viewAndSubmitJob.click({ timeout: 2000 }) + async click_viewJobOutput(){ + await this.viewJobOutput.click({ timeout: 2000 }) } async click_previewJob(){ - this.view_job_output.click({ timeout: 2000 }) + await this.view_job_output.click({ timeout: 2000 }) } async is_skipLaunchConfigButtonEnable(){ return await this.skip_button.isEnabled({ timeout: 5000 }); @@ -116,8 +117,8 @@ class LaunchConfigPage{ async click_skipLaunhConfig(){ await this.skip_button.click({ timeout: 2000 }); - const certificatePage_title = await this.certificateTab_title.textContent(); - return certificatePage_title; + const reviewPage_title = await this.reviewPage_title.textContent(); + return reviewPage_title; } async isPreviousButtonEnable(){ @@ -126,8 +127,8 @@ class LaunchConfigPage{ async returnTitleOfPrevPage(){ await this.previous_step_button.click({ timeout: 2000 }); - const certificate_title = await this.certificateTab_title.textContent(); - return certificate_title; + const caching_service_title = await this.cachingService_title.textContent(); + return caching_service_title; } async open_monacoEditor(){ @@ -140,7 +141,7 @@ class LaunchConfigPage{ return await this.continue_ReviewSelector.isDisabled({ timeout: 5000 }); } async click_saveAndClose(){ - this.save_and_close.click({ timeout: 2000 }) + await this.save_and_close.click({ timeout: 2000 }) } async read_yaml() { let previousScrollHeight = 0; @@ -159,7 +160,6 @@ class LaunchConfigPage{ // Append the new text to the existing text allText += newText; - console.log(allText) // Scroll a little to load more content await this.page.evaluate(() => { @@ -185,10 +185,9 @@ class LaunchConfigPage{ previousScrollHeight = currentScrollHeight; } - console.log('All text:', allText); return allText; } } - export default LaunchConfigPage; \ No newline at end of file + export default LaunchConfigPage; diff --git a/playwright_test/Pages/networking.page.ts b/playwright_test/Pages/networking.page.ts index c654df8a..4ddbb9a0 100644 --- a/playwright_test/Pages/networking.page.ts +++ b/playwright_test/Pages/networking.page.ts @@ -96,13 +96,30 @@ class NetworkingPage{ 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 ")]'); - //*[@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"]'); + } + async isCheckBoxChecked(component: string,label:string): Promise { + const checkboxLocator = this.page.locator(`//span[./strong[text()="${component}"]]/following-sibling::div//label[span[text()="${label}"]]//input[@type="checkbox"]`); + + try { + if (await checkboxLocator.isChecked()) { + console.log("Checkbox is already checked."); + return true; + } else { + await checkboxLocator.check(); + console.log("Checkbox has been checked."); + return true; + } + } catch (error) { + console.error("Failed to toggle the checkbox:", error); + return false; + } + } async movetoNetworkingPage(){ await this.licenseAgreement.click({timeout: 9000}) await this.acceptLicense.click({timeout: 9000}) @@ -212,13 +229,13 @@ class NetworkingPage{ await this.view_yaml.click({ timeout: 5000 }) } async closeButton(){ - this.close_button.click({ timeout: 2000 }) + await this.close_button.click({ timeout: 2000 }) } async click_viewAndSubmitJob(){ - this.viewAndSubmitJob.click({ timeout: 2000 }) + await this.viewAndSubmitJob.click({ timeout: 2000 }) } async click_previewJob(){ - this.view_job_output.click({ timeout: 2000 }) + await this.view_job_output.click({ timeout: 2000 }) } async is_skipNetworkingButtonEnable(){ return await this.skip_button.isEnabled({ timeout: 5000 }); @@ -244,7 +261,7 @@ class NetworkingPage{ } async open_monacoEditor(){ - this.view_yaml.click({ timeout: 5000 }) + await this.view_yaml.click({ timeout: 5000 }) const editor_title = await this.editor_title_element.textContent(); return editor_title; } @@ -253,7 +270,7 @@ class NetworkingPage{ return await this.continue_ReviewSelector.isDisabled({ timeout: 5000 }); } async click_saveAndClose(){ - this.save_and_close.click({ timeout: 2000 }) + await this.save_and_close.click({ timeout: 2000 }) } async read_yaml() { let previousScrollHeight = 0; @@ -288,4 +305,4 @@ class NetworkingPage{ } - export default NetworkingPage; \ No newline at end of file + export default NetworkingPage; diff --git a/playwright_test/Pages/planning.page.ts b/playwright_test/Pages/planning.page.ts index a59ed51e..658f20c1 100644 --- a/playwright_test/Pages/planning.page.ts +++ b/playwright_test/Pages/planning.page.ts @@ -54,7 +54,6 @@ class PlanningPage{ 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']") - this.saveAndClose = page.locator("//button[contains(text(),'Save & close')]") this.previousStep = page.locator("//button[contains(text(),'Previous step')]") this.continueInstallationOptions = page.locator("//button[contains(text(), 'Continue to Installation Options')]") this.readyToProceedMessage = page.locator("//div[contains(@class,'MuiBox-root css-hieomr')]/p") @@ -73,7 +72,8 @@ class PlanningPage{ } async click_saveAndClose(){ - this.save_and_close.click({ timeout: 2000 }) + await this.page.waitForTimeout(5000); + await this.save_and_close.click({ timeout: 2000 }) } async enterJobStatement(jobStatement: string){ @@ -87,6 +87,7 @@ class PlanningPage{ async isSaveAndValidateGreenCheckVisible(): Promise { try { + await this.page.waitForTimeout(500); await this.saveAndValidateGreenCheck.waitFor({ state: 'visible', timeout: 10000 }); return true; } catch (error) { @@ -198,7 +199,7 @@ class PlanningPage{ async clickValidateLocations(){ await this.validateLocations.click({timeout: 5000}); - await this.isContinueToInstallationEnabled() + await this.waitForContinueButtonToBeEnabled(); } async isValidateLocationsGreenCheckVisible(): Promise { @@ -213,7 +214,8 @@ class PlanningPage{ async clickSaveAndClose(){ - await this.saveAndClose.click({timeout: 15000}); + await this.page.waitForTimeout(5000); + await this.save_and_close.click({ timeout: 5000 }) } async clickPreviousStep(){ @@ -235,21 +237,25 @@ class PlanningPage{ await new Promise(resolve => setTimeout(resolve, interval)); } await this.continueInstallationOptions.click(); - } +} async isContinueToInstallationDisabled(){ await this.page.waitForTimeout(500); return await this.continueInstallationOptions.isDisabled() } + async isContinueToInstallationEnabled(){ + await this.page.waitForTimeout(500); + return await this.continueInstallationOptions.isEnabled() + } async getReadyToProceedMessage(){ await this.page.waitForTimeout(1000); return await this.readyToProceedMessage.textContent({ timeout: 2000 }); } - async isContinueToInstallationEnabled(){ + async isContinueToInstallationDisabled(){ await this.page.waitForTimeout(500); - return await this.continueInstallationOptions.isEnabled() + return await this.continueInstallationOptions.isDisabled() } async clickSaveValidate(){ @@ -274,4 +280,4 @@ class PlanningPage{ } } - export default PlanningPage; \ No newline at end of file + export default PlanningPage; diff --git a/playwright_test/Pages/security.page.ts b/playwright_test/Pages/security.page.ts index 91c7076d..4a950350 100644 --- a/playwright_test/Pages/security.page.ts +++ b/playwright_test/Pages/security.page.ts @@ -46,8 +46,8 @@ class SecurityPage{ 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.mainXpath = '//html/body/div/div[2]/div/div[4]/div/form/div/div[3]/div[1]/div[3]/div/div[2]/div/div/div' - this.stc_mainXpath = '//html/body/div[1]/div[2]/div/div[4]/div/form/div/div[3]/div[1]/div[4]/div/div[2]/div/div/div/' + this.mainXpath = '//html/body/div/div[2]/div/div[4]/div/form/div/div[2]/div[1]/div[3]/div/div[2]/div/div/div' + this.stc_mainXpath = '//html/body/div/div[2]/div/div[4]/div/form/div/div[2]/div[1]/div[4]/div/div[2]/div/div/div' this.product = page.locator('input[role="combobox"]') this.view_yaml = page.locator('//button[contains(text(),"View/Edit Yaml")]') this.viewAndSubmitJob = page.locator('//button[contains(text(), "View Job Output")]') @@ -58,18 +58,19 @@ class SecurityPage{ 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.stc_title = page.locator('//div[text()="Stcs"]') this.securityTab_title = page.locator('//div[text()="Security"]') + this.click_security = page.locator('//span[text()="Security"]') this.continue_CertificateSelector = page.locator('//button[contains(text(), "Continue to STC Setup")]') - this.admin = page.getByLabel('Admin'); - this.stc = page.getByLabel('Stc'); - this.sys_prog = page.getByLabel('Sys Prog'); - this.user_zis = page.locator(this.mainXpath +'/div/div/div[2]/div/div/input'); - this.user_zowe = page.locator(this.mainXpath +'/div/div/div[1]/div/div/input'); + this.admin = page.locator('//html/body/div/div[2]/div/div[4]/div/form/div/div[2]/div[1]/div[2]/div/div[2]/div/div/div/div[1]/div/div[1]/div/div/input'); + this.stc = page.locator('//html/body/div/div[2]/div/div[4]/div/form/div/div[2]/div[1]/div[2]/div/div[2]/div/div/div/div[1]/div/div[2]/div/div/input'); + this.sys_prog = page.locator('//html/body/div/div[2]/div/div[4]/div/form/div/div[2]/div[1]/div[2]/div/div[2]/div/div/div/div[2]/div/div/div/div/input'); + this.user_zis = page.locator(this.mainXpath +'/div/div/div[2]/div/label'); + this.user_zowe = page.locator(this.mainXpath +'/div/div/div[1]/div/label'); this.aux = page.getByLabel('Aux'); - this.stc_zowe = page.locator(this.stc_mainXpath + 'div[1]/div/div[1]/div/div/input'); - this.stc_zis = page.locator(this.stc_mainXpath + 'div[1]/div/div[2]/div/div/input'); + this.stc_zowe = page.locator(this.stc_mainXpath + '/div[1]/div/div[1]/div/label'); + this.stc_zis = page.locator(this.stc_mainXpath + '/div[1]/div/div[2]/div/label'); } @@ -78,28 +79,31 @@ class SecurityPage{ } async movetoSecurityPage(){ - await this.licenseAgreement.click({timeout: 9000}) - await this.acceptLicense.click({timeout: 9000}) - await this.continueToComponentInstallation.click({timeout: 5000}) - await this.skip_button.click() - await this.skip_button.click() + await this.click_security.click({timeout: 5000}) } async fillProduct(product:string){ await this.product.fill(product,{ timeout: 10000 }) } - async fillSecurityDetails(product:string, admin:string,stc:string,sys_prog:string,user_zis:string,user_zowe:string,aux: string, stc_zowe: string, stc_zis:string){ - await this.product.fill(product,{ timeout: 10000 }) - await this.page.waitForTimeout(8000); - await this.admin.fill(admin,{ timeout: 10000 }) - await this.stc.fill(stc,{ timeout: 10000 }) - await this.sys_prog.fill(sys_prog,{ timeout: 10000 }) - await this.page.waitForTimeout(8000); - await this.user_zis.fill(user_zis,{ timeout: 10000 }) - await this.user_zowe.fill(user_zowe,{ timeout: 10000 }) - await this.page.waitForTimeout(8000); - await this.aux.fill(aux,{ timeout: 10000 }) - await this.stc_zowe.fill(stc_zowe,{ timeout: 10000 }) - await this.stc_zis.fill(stc_zis,{ timeout: 10000 }) + async fillSecurityDetails(product:string, admin:string,stc:string,sys_prog:string,user_zis:string,user_zowe:string,aux: string, stc_zowe: string, stc_zis:string){await this.page.waitForTimeout(1000); + await this.product.fill(product) + await this.page.waitForTimeout(1000); + await this.admin.fill(admin) + await this.page.waitForTimeout(1000); + await this.stc.fill(stc); + await this.page.waitForTimeout(1000); + await this.sys_prog.fill(sys_prog) + await this.page.waitForTimeout(1000); + await this.user_zis.fill(user_zis) + await this.page.waitForTimeout(1000); + await this.user_zowe.fill(user_zowe) + await this.page.waitForTimeout(1000); + await this.aux.fill(aux) + await this.page.waitForTimeout(1000); + await this.stc_zowe.fill(stc_zowe) + await this.page.waitForTimeout(1000); + await this.stc_zis.fill(stc_zis) + await this.page.waitForTimeout(1000); + } async fillAdmin(admin:string){ @@ -108,7 +112,27 @@ class SecurityPage{ async initializeSecurity(){ await this.initSecurity.click() + await this.waitForContinueButtonToBeEnabled(); + } + + async isContinueButtonEnabled(){ + return await this.continue_CertificateSelector.isEnabled(); } + + private async waitForContinueButtonToBeEnabled(): Promise { + const timeout = 100000; + const interval = 500; + const endTime = Date.now() + timeout; + while (Date.now() < endTime) { + if (await this.isContinueButtonEnabled()) { + return; + } + await this.page.waitForTimeout(interval); + } + + throw new Error('Continue button was not enabled within the timeout period'); + } + async isWriteConfigGreenCheckVisible(){ return await this.writeConfig_greenCheckXpath.isVisible({ timeout: 50000 }); } @@ -133,13 +157,13 @@ class SecurityPage{ await this.view_yaml.click({ timeout: 2000 }) } async closeButton(){ - this.close_button.click({ timeout: 2000 }) + await this.close_button.click({ timeout: 2000 }) } async click_viewAndSubmitJob(){ - this.viewAndSubmitJob.click({ timeout: 2000 }) + await this.viewAndSubmitJob.click({ timeout: 2000 }) } async click_previewJob(){ - this.view_job_output.click({ timeout: 2000 }) + await this.view_job_output.click({ timeout: 2000 }) } async is_skipSecurityButtonEnable(){ return await this.skip_button.isEnabled({ timeout: 5000 }); @@ -150,7 +174,7 @@ class SecurityPage{ } async open_monacoEditor(){ - this.view_yaml.click({ timeout: 2000 }) + await this.view_yaml.click({ timeout: 2000 }) const editor_title = await this.editor_title_element.textContent(); return editor_title; } @@ -159,39 +183,41 @@ class SecurityPage{ return await this.continue_CertificateSelector.isDisabled({ timeout: 5000 }); } async click_saveAndClose(){ - this.save_and_close.click({ timeout: 2000 }) + await this.save_and_close.click({ timeout: 2000 }) } async get_admin_value(){ - const admin_value = await this.admin.textContent(); + const admin_value = await this.admin.inputValue(); return admin_value; } async get_stc_value(){ - const stc_value = await this.stc.textContent(); - return stc_value; + await this.page.waitForTimeout(5000); + return await this.stc.inputValue({timeout:2000}); } async get_user_zowe_value(){ - const userZowe_value = await this.user_zowe.textContent(); + const userZowe_value = await this.user_zowe.inputValue(); return userZowe_value; } async get_user_zis_value(){ - const userZis_value = await this.user_zis.textContent(); + const userZis_value = await this.user_zis.inputValue(); return userZis_value; } async get_aux_value(){ - const aux_value = await this.aux.textContent(); - return aux_value; + return await this.aux.inputValue(); } async get_stc_zis_value(){ - const stcZis_value = await this.stc_zis.textContent(); - return stcZis_value; + return await this.stc_zis.inputValue(); +// const stcZis_value = await this.stc_zis.textContent(); +// return stcZis_value; } async get_stc_zowe_value(){ - const stcZowe_value = await this.stc_zowe.textContent(); - return stcZowe_value; + return await this.stc_zowe.inputValue(); +// const stcZowe_value = await this.stc_zowe.textContent(); +// return stcZowe_value; } async get_sysProg_value(){ - const sysProg_value = await this.sys_prog.textContent(); + const sysProg_value = await this.sys_prog.inputValue(); + console.log(sysProg_value); return sysProg_value; } async returnTitleOfSecurityPage(){ @@ -211,4 +237,4 @@ class SecurityPage{ } -export default SecurityPage; \ No newline at end of file +export default SecurityPage; diff --git a/playwright_test/Pages/stcs.page.ts b/playwright_test/Pages/stcs.page.ts index d93eec1b..c450e81f 100644 --- a/playwright_test/Pages/stcs.page.ts +++ b/playwright_test/Pages/stcs.page.ts @@ -1,18 +1,248 @@ -import { Page, Locator } from '@playwright/test'; +import { Page,ElectronApplication, Locator,_electron as electron } from '@playwright/test'; +let electronApp: ElectronApplication -class StcsPage { +class StcsPage{ page: Page; - pageTitle: Locator; + click_stcs = Locator; + Security_title = Locator; + zis = Locator; + zowe = Locator; + aux = Locator; + dataset_proclib = Locator; + readYaml = Locator; + initSTC = Locator; + previous_step_button = Locator; + skip_button = Locator; + editor_title_element = Locator; + STCS_TITLE = Locator; + continueToComponentInstallation = Locator; + view_yaml = Locator; + viewAndSubmitJob = Locator; + view_job_output = Locator; + save_and_close = Locator; + previous_step = Locator; + skip_button = Locator; + close_button = Locator; + certificateTab_title = Locator; + continue_ReviewSelector = Locator; + errorMsg = Locator; + continue_CertificateSelector = Locator; + get_zoweValue = Locator; + get_zisValue = Locator; + get_auxValue = Locator; + get_datasetProclib = Locator; + writeConfig_greenCheckXpath = Locator; + uploadYaml_greenCheckXpath = Locator; + init_stcs_greenCheckXpath = Locator; + + constructor(page: Page) { this.page = page; - this.pageTitle = page.locator("//div[@class='MuiBox-root css-la96ob']/div") + this.click_stcs = page.locator('//span[text()="Stcs"]') + this.Security_title = page.locator('//div[text()="Security"]') + this.zis = page.getByLabel('Zis'); + this.zowe = page.getByLabel('Zowe'); + this.aux = page.getByLabel('Aux'); + this.dataset_proclib = page.getByLabel('Dataset Proclib'); + this.readYaml = page.locator('div.view-lines') + this.initSTC = page.locator('//button[contains(text(),"Initialize STC Config")]') + 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.STCS_TITLE = page.locator(' //div[text()="Stcs"]') + this.continueToComponentInstallation = page.locator('//button[contains(text(), "Continue to Components Installation")]') + 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(), "View Job Output")]') + 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.certificateTab_title = page.locator('//div[text()="Certificates"]') + this.continue_ReviewSelector = page.locator('//button[contains(text(), "Review")]') + this.errorMsg = page.locator('//p[text()="is a required property"]') + this.continue_CertificateSelector = page.locator('//button[contains(text(), "Continue to Certificates Setup")]') + this.get_zoweValue = page.locator('//html/body/div/div[2]/div/div[4]/div/form/div/div[2]/div[2]/div[1]/div/input') + this.get_zisValue = page.locator('//html/body/div/div[2]/div/div[4]/div/form/div/div[2]/div[2]/div[2]/div/input') + this.get_auxValue = page.locator('//html/body/div/div[2]/div/div[4]/div/form/div/div[2]/div[2]/div[3]/div/input') + this.get_datasetProclib = page.locator('//html/body/div/div[2]/div/div[4]/div/form/div/div[2]/div[2]/div[4]/div/input') + this.writeConfig_greenCheckXpath = page.locator('#card-init-stcs-progress-card') + this.uploadYaml_greenCheckXpath = page.locator('#card-download-progress-card') + this.init_stcs_greenCheckXpath = page.locator("#card-success-progress-card") + } + + async movetoStcsPage(){ + await this.page.waitForTimeout(2000); + await this.click_stcs.click({timeout: 5000}) + } + async returnTitleOfStcsPage(){ + const Stcs_title = await this.STCS_TITLE.textContent(); + return Stcs_title; + } + async get_zowe_value(){ + const value = await this.get_zoweValue.evaluate(el => el.value); + return value; + } + + async get_validation_error_msg(){ + const errorText = await this.page.locator('//p[text()="is a required property"]').textContent(); + return errorText; + } + + async get_zis_value(){ + const value = await this.get_zisValue.evaluate(el => el.value); + console.log("zis value is", value) + return value; + } + + async get_aux_value(){ + const value = await this.get_auxValue.evaluate(el => el.value); + return value; + } + + async get_datasetProclib_value(){ + const value = await this.get_datasetProclib.evaluate(el => el.value); + return value; + } + + async viewYaml(){ + await this.view_yaml.click({ timeout: 5000 }) + } + async closeButton(){ + await this.close_button.click({ timeout: 5000 }) + } + async click_viewAndSubmitJob(){ + await this.viewAndSubmitJob.click({ timeout: 2000 }) + } + async click_previewJob(){ + await this.view_job_output.click({ timeout: 5000 }) + } + async click_skipStcsButton(){ + await this.skip_button.click({ timeout: 2000 }); + const certificate_title = await this.certificateTab_title.textContent(); + return certificate_title; + } + async is_skipStcsButtonEnable(){ + return await this.skip_button.isEnabled({ timeout: 5000 }); + } + + + async isPreviousButtonEnable(){ + return await this.previous_step.isEnabled({ timeout: 50000 }); + } + + async returnTitleOfPrevPage(){ + await this.previous_step_button.click({ timeout: 2000 }); + const security_title = await this.Security_title.textContent(); + return security_title; + } + + async open_monacoEditor(){ + await this.view_yaml.click({ timeout: 5000 }) + const editor_title = await this.editor_title_element.textContent(); + return editor_title; + } + + async isWriteConfigGreenCheckVisible(){ + return await this.writeConfig_greenCheckXpath.isVisible({ timeout: 50000 }); + } + async isUploadConfigGreenCheckVisible(){ + return await this.uploadYaml_greenCheckXpath.isVisible({ timeout: 50000 }); + } + async isInitSTCSGreenCheckVisible(){ + return await this.init_stcs_greenCheckXpath.isVisible({ timeout: 50000 }); + } + + async click_saveAndClose(){ + await this.save_and_close.click({ timeout: 5000 }) } + async isContinueButtonDisable(){ + return await this.continue_CertificateSelector.isDisabled(); + } + + async isContinueButtonEnabled(){ + return await this.continue_CertificateSelector.isEnabled(); + } - async getStcsPageTitle() { - await this.page.waitForTimeout(500); - return await this.pageTitle.textContent({ timeout: 2000 }); + async initializeSTC(){ + await this.initSTC.click(); + await this.waitForContinueButtonToBeEnabled(); } + + private async waitForContinueButtonToBeEnabled(): Promise { + const timeout = 100000; + const interval = 500; + const endTime = Date.now() + timeout; + while (Date.now() < endTime) { + if (await this.isContinueButtonEnabled()) { + return; + } + await this.page.waitForTimeout(interval); + } + + throw new Error('Continue button was not enabled within the timeout period'); + } + + async read_yaml() { + let previousScrollHeight = 0; + let allText = ''; + + while (true) { + const newText = await this.page.evaluate(() => { + const viewLines = document.querySelectorAll('.view-lines .view-line'); + let text = ''; + viewLines.forEach((line) => { + text += line.textContent + '\n'; + }); + return text; + }); + allText += newText; + console.log(allText) + await this.page.evaluate(() => { + const editor = document.querySelector('.monaco-scrollable-element.editor-scrollable.vs'); + editor.scrollTop += 100; + }); + + 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 (currentScrollHeight === previousScrollHeight) { + break; + } + previousScrollHeight = currentScrollHeight; + } + + console.log('All text:', allText); + return allText; +} + async isStatusChecked() { + try { + await this.page.waitForTimeout(1000); + + const isGreen = await this.page.evaluate(() => { + const svgElement = document.querySelector('#zen-root-container > div.wizard-container > div > div.MuiStepper-root.MuiStepper-horizontal.substepper.css-m5vj9m-MuiStepper-root > div:nth-child(9) > span > span.MuiStepLabel-iconContainer.Mui-active.Mui-error.css-vnkopk-MuiStepLabel-iconContainer > svg'); + + if (!svgElement) { + return false; + } + const style = window.getComputedStyle(svgElement); + + return style.color === 'green' || style.fill === 'green'; + }); + + return isGreen; + } catch (error) { + console.error('Error in isStatusChecked:', error); + return false; + } +} + + } -export default StcsPage; \ No newline at end of file + export default StcsPage; diff --git a/playwright_test/Pages/title.page.ts b/playwright_test/Pages/title.page.ts index 0cb0a10a..14615a23 100644 --- a/playwright_test/Pages/title.page.ts +++ b/playwright_test/Pages/title.page.ts @@ -9,7 +9,7 @@ class TitlePage { constructor(page: Page) { this.page = page; this.zoweInstallButton = page.locator('#card-install') - this.zoweDryrunButton = page.locator('#card-configure') + this.zoweDryrunButton = page.locator('//*[@id="card-dry run"]') this.resumeProgressButton = page.locator("//button[text()='Resume Progress']") } @@ -23,4 +23,4 @@ class TitlePage { } - export default TitlePage; \ No newline at end of file + export default TitlePage; diff --git a/playwright_test/Pages/vsam.page.ts b/playwright_test/Pages/vsam.page.ts index 543ea86d..66a5b8cc 100644 --- a/playwright_test/Pages/vsam.page.ts +++ b/playwright_test/Pages/vsam.page.ts @@ -1,16 +1,290 @@ -import { Page, Locator } from '@playwright/test'; +import { Page,ElectronApplication, Locator,_electron as electron } from '@playwright/test'; +let electronApp: ElectronApplication -class VsamPage { +class VsamPage{ page: Page; - pageTitle: Locator; + Security_title = Locator; + readYaml = Locator; + previous_step_button = Locator; + skip_button = Locator; + editor_title_element = Locator; + VSAM_TITLE = Locator; + continueToComponentInstallation = Locator; + view_yaml = Locator; + viewAndSubmitJob = Locator; + view_job_output = Locator; + save_and_close = Locator; + previous_step = Locator; + skip_button = Locator; + close_button = Locator; + certificateTab_title = Locator; + errorMsg = Locator; + Error = Locator; + invalidInput_msg = Locator; + writeConfig_greenCheckXpath = Locator; + uploadYaml_greenCheckXpath = Locator; + init_stcs_greenCheckXpath = Locator; + + constructor(page: Page) { this.page = page; - this.pageTitle = page.locator("//div[@class='MuiBox-root css-la96ob']/div") + this.click_vsam = page.locator('//span[text()="Caching Service"]') + this.Security_title = page.locator('//div[text()="Security"]') + this.Mode = page.locator('//html/body/div/div[2]/div/div[4]/div/form/div/div[2]/div[2]/div[1]/div/div/label'); + this.volume = page.getByLabel('Volume'); + this.StorageClass = page.getByLabel('Storage Class'); + this.VsamDatasetName = page.getByLabel('Name'); + this.dataset_proclib = page.getByLabel('Dataset Proclib'); + this.click_dropDown = page.locator('//*[@id="container-box-id"]/form/div/div[2]/div[1]/div/svg') + this.storage_mode = page.getByLabel('Storage Mode') + this.readYaml = page.locator('div.view-lines') + this.initVSAM = page.locator('//button[contains(text(),"Initialize Vsam Config")]') + 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.VSAM_TITLE = page.locator(' //div[text()="CachingService"]') + this.continueToComponentInstallation = page.locator('//button[contains(text(), "Continue to Components Installation")]') + 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(), "View Job Output")]') + 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.certificateTab_title = page.locator('//div[text()="Certificates"]') + this.LaunchConfigTab_title = page.locator('//div[text()="Configuration"]') + this.errorMsg = page.locator('//p[text()="is a required property"]') + this.continue_LaunchConfigSelector = page.locator('//button[contains(text(), "Continue to Launch Setup")]') + this.writeConfig_greenCheckXpath = page.locator('#card-init-vsam-progress-card') + this.uploadYaml_greenCheckXpath = page.locator('#card-download-progress-card') + this.init_vsam_greenCheckXpath = page.locator("#card-success-progress-card") + this.Error = page.locator('//div[@class="MuiAlert-message css-1pxa9xg-MuiAlert-message"]') + this.invalidInput_msg = page.locator('p.MuiFormHelperText-root.Mui-error') + } + + async movetoVsamPage(){ + await this.click_vsam.click({timeout: 5000}) + } + async returnTitleOfVsamPage(){ + const Vsam_title = await this.VSAM_TITLE.textContent(); + return Vsam_title; + } + + async select_storageMode(storage_mode:string){ + await this.page.waitForTimeout(1000); + await this.storage_mode.click({timeout: 5000}); + const itemLocator = this.page.locator(`//li[text()="${storage_mode}"]`); + await itemLocator.waitFor({ state: 'visible' }); + await itemLocator.click(); + } + + async fillVsamDetails(mode:string, volume:string,storage_class:string,VsamDatasetName:string){ + await this.page.waitForTimeout(1000); + await this.Mode.fill(mode) + await this.page.waitForTimeout(1000); + await this.volume.fill(volume) + await this.page.waitForTimeout(1000); + await this.StorageClass.fill(storage_class) + await this.page.waitForTimeout(1000); + await this.VsamDatasetName.fill(VsamDatasetName) + await this.page.waitForTimeout(2000); + } + async get_VsamMode_value(): Promise { + await this.page.waitForTimeout(2000); + return await this.Mode.inputValue(); + } + + async get_VsamVolume_value(){ + return await this.volume.inputValue(); + } + + async get_StorageClass_value(){ + return await this.StorageClass.inputValue(); + } + + async get_VsamDatasetName_value(){ + return await this.VsamDatasetName.inputValue(); + } + + async fillVsamDatasetName(VsamDatasetName:string){ + await this.page.waitForTimeout(1000); + await this.VsamDatasetName.fill(VsamDatasetName) + } + + async viewYaml(){ + await this.view_yaml.click({ timeout: 5000 }) + } + async closeButton(){ + await this.close_button.click({ timeout: 2000 }) + } + async click_viewAndSubmitJob(){ + await this.viewAndSubmitJob.click({ timeout: 2000 }) + } + async click_previewJob(){ + await this.view_job_output.click({ timeout: 2000 }) + } + async click_skipVsamButton(){ + await this.skip_button.click({ timeout: 2000 }); + const launchConfigPage_title = await this.LaunchConfigTab_title.textContent(); + return launchConfigPage_title; + } + async is_skipVsamButtonEnable(){ + return await this.skip_button.isEnabled({ timeout: 5000 }); + } + + async is_initVsamButtonVisible() { + return await this.initVSAM.isVisible({ timeout: 5000 }); + } + + async is_initVsamButtonVisible() { + return await this.initVSAM.isVisible({ timeout: 5000 }); + } + + async isElement_Visible(element) { + try { + return await element.isVisible(); + } catch (error) { + return false; + } +} + + + async isPreviousButtonEnable(){ + return await this.previous_step.isEnabled({ timeout: 50000 }); + } + + async returnTitleOfPrevPage(){ + await this.previous_step_button.click({ timeout: 2000 }); + const certificate_title = await this.certificateTab_title.textContent(); + return certificate_title; } - async getVsamPageTitle() { - await this.page.waitForTimeout(500); - return await this.pageTitle.textContent({ timeout: 2000 }); + + async open_monacoEditor(){ + await this.view_yaml.click({ timeout: 5000 }) + const editor_title = await this.editor_title_element.textContent(); + return editor_title; + } + + async isWriteConfigGreenCheckVisible(){ + return await this.writeConfig_greenCheckXpath.isVisible({ timeout: 50000 }); + } + async isUploadConfigGreenCheckVisible(){ + return await this.uploadYaml_greenCheckXpath.isVisible({ timeout: 50000 }); + } + async isInitVSAMGreenCheckVisible(){ + return await this.init_vsam_greenCheckXpath.isVisible({ timeout: 50000 }); + } + + async click_saveAndClose(){ + await this.save_and_close.click({ timeout: 5000 }) + } + + async isContinueButtonDisable(){ + return await this.continue_LaunchConfigSelector.isDisabled(); + } + + async isContinueButtonEnabled(){ + return await this.continue_LaunchConfigSelector.isEnabled(); + } + + async invalidInput_ErrorMsg(){ + return await this.invalidInput_msg.textContent(); + } + + async initializeVSAM(){ + await this.initVSAM.click(); + await this.waitForContinueButtonToBeEnabled(); + } + + async waitForErrorMsg(){ + const timeout = 1000000; + const interval = 500; + const endTime = Date.now() + timeout; + while (Date.now() < endTime) { + errorMsg = await this.Error.textContent(); + if (errorMsg) { + return errorMsg; + } + await this.page.waitForTimeout(interval); + } + + throw new Error('Error message was not found within the timeout period'); } + + + private async waitForContinueButtonToBeEnabled(): Promise { + const timeout = 1000000; + const interval = 500; + const endTime = Date.now() + timeout; + while (Date.now() < endTime) { + if (await this.isContinueButtonEnabled()) { + return; + } + await this.page.waitForTimeout(interval); + } + + throw new Error('Continue button was not enabled within the timeout period'); + } + + async read_yaml() { + let previousScrollHeight = 0; + let allText = ''; + + while (true) { + const newText = await this.page.evaluate(() => { + const viewLines = document.querySelectorAll('.view-lines .view-line'); + let text = ''; + viewLines.forEach((line) => { + text += line.textContent + '\n'; + }); + return text; + }); + allText += newText; + console.log(allText) + await this.page.evaluate(() => { + const editor = document.querySelector('.monaco-scrollable-element.editor-scrollable.vs'); + editor.scrollTop += 100; + }); + + 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 (currentScrollHeight === previousScrollHeight) { + break; + } + previousScrollHeight = currentScrollHeight; + } + + console.log('All text:', allText); + return allText; +} + async isStatusChecked() { + try { + await this.page.waitForTimeout(1000); + + const isGreen = await this.page.evaluate(() => { + const svgElement = document.querySelector('#zen-root-container > div.wizard-container > div > div.MuiStepper-root.MuiStepper-horizontal.substepper.css-m5vj9m-MuiStepper-root > div:nth-child(13) > span > span.MuiStepLabel-iconContainer.Mui-active.Mui-error.css-vnkopk-MuiStepLabel-iconContainer > svg'); + + if (!svgElement) { + return false; + } + const style = window.getComputedStyle(svgElement); + + return style.color === 'green' || style.fill === 'green'; + }); + + return isGreen; + } catch (error) { + console.error('Error in isStatusChecked:', error); + return false; + } +} + + } -export default VsamPage; \ No newline at end of file + export default VsamPage; diff --git a/playwright_test/Tests/ApfAuth.spec.ts b/playwright_test/Tests/ApfAuth.spec.ts index 5d4b797d..f9afad77 100644 --- a/playwright_test/Tests/ApfAuth.spec.ts +++ b/playwright_test/Tests/ApfAuth.spec.ts @@ -21,11 +21,12 @@ const SECURITY_TITLE = 'Security' test.beforeAll(async () => { + test.setTimeout(600000); try { await prepareEnvironment({ install: true, remove: false }); } catch (error) { console.error('Error during environment preparation:', error); - process.exit(1); + process.exit(1); } }); @@ -55,22 +56,19 @@ test.describe('ApfAuthTab', () => { 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.ZOWE_WORKSPACE_DIR, + config.ZOWE_EXTENSION_DIR, + config.ZOWE_LOG_DIR, + 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.clickOnContinueToUnpax() await installationTypePage.skipUnpax() await installationPage.fillAllFields(config.DATASET_PREFIX, config.PARM_LIB, @@ -89,23 +87,7 @@ test.describe('ApfAuthTab', () => { test.afterEach(async () => { await electronApp.close() }) - test('Test Resume Progress', async ({ page }) => { - apfAuthPage.fillApfDetails(config.DATASET_PREFIX, config.AUTH_LOAD_LIB, config.AUTH_PLUGIN_LIB) - apfAuthPage.click_saveAndClose() - connectionPage.click_resumeProgress() - const title = await apfAuthPage.returnTitleOfApfAuthPage(); - 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(config.DATASET_PREFIX); - expect(AuthLoadLib_Value).toBe(config.AUTH_LOAD_LIB); - expect(AuthPluginLib_Value).toBe(config.AUTH_PLUGIN_LIB); - }) - test('Verify title', async ({ page }) => { - apfAuthPage.fillApfDetails(DATASET_PREFIX,AUTH_LOAD_LIB,AUTH_PLUGIN_LIB) - apfAuthPage.movetoApfAuthPage() await expect(apfAuthPage.datasetPrefix).toBeTruthy() await expect(apfAuthPage.authLoadLib).toBeTruthy() await expect(apfAuthPage.authpluginLib).toBeTruthy() @@ -115,96 +97,63 @@ test.describe('ApfAuthTab', () => { await expect(apfAuthPage.previous_step).toBeTruthy() await expect(apfAuthPage.skip_apf_auth).toBeTruthy() await expect(apfAuthPage.continue_security_setup).toBeTruthy() - - }) - test('test apfAuth with empty data', async ({ page }) => { - apfAuthPage.fillApfDetails('','','') - apfAuthPage.movetoApfAuthPage() - apfAuthPage.initializeApfauth() - const isWriteConfig_check_visible = await apfAuthPage.isWriteConfigGreenCheckVisible(); - expect(isWriteConfig_check_visible).toBe(false); - const isUploadConfig_check_visible = await apfAuthPage.isUploadConfig_check_visible(); - expect(isUploadConfig_check_visible).toBe(false); - const isInitApf_check_visible = await apfAuthPage.isInitApf_check_visible(); - expect(isInitApf_check_visible).toBe(false); }) + test('test apfAuth with valid data', async ({ page }) => { - apfAuthPage.fillApfDetails(DATASET_PREFIX,AUTH_LOAD_LIB,AUTH_PLUGIN_LIB) - apfAuthPage.movetoApfAuthPage() - apfAuthPage.initializeApfauth() + await apfAuthPage.initializeApfauth() const isWriteConfig_check_visible = await apfAuthPage.isWriteConfigGreenCheckVisible(); - expect(isWriteConfig_check_visible).toBe(true); - const isUploadConfig_check_visible = await apfAuthPage.isUploadConfig_check_visible(); - expect(isUploadConfig_check_visible).toBe(true); - const isInitApf_check_visible = await apfAuthPage.isInitApf_check_visible(); - expect(isInitApf_check_visible).toBe(true); + await expect(isWriteConfig_check_visible).toBe(true); + const isUploadConfig_check_visible = await apfAuthPage.isUploadConfigGreenCheckVisible(); + await expect(isUploadConfig_check_visible).toBe(true); + const isInitApf_check_visible = await apfAuthPage.isInitApfGreenCheckVisible(); + await expect(isInitApf_check_visible).toBe(true); }) - test('click Previous step', async ({ page }) => { - apfAuthPage.movetoApfAuthPage() + test('Click Previous Step and verify that the Previous button is enabled.', async ({ page }) => { + const is_prevButtonEnable = await apfAuthPage.isPreviousButtonEnable(); + expect(is_prevButtonEnable).toBe(true); const title = await apfAuthPage.returnTitleOfPrevPage(); expect(title).toBe(NETWORKING_TITLE); }) - test('test skip apfAuth button is enable', async ({ page }) => { - apfAuthPage.movetoApfAuthPage() + test('test skip apfAuth button is enable and click Skip button', async ({ page }) => { const isSkipApfAuthEnable = await apfAuthPage.is_skipApfAuthButtonEnable(); expect(isSkipApfAuthEnable).toBe(true); + const security_title = await apfAuthPage.click_skipApfAuth(); + expect(security_title).toBe(SECURITY_TITLE); }) - test('test previous button is enabled', async ({ page }) => { - apfAuthPage.movetoApfAuthPage() - const is_prevButtonEnable = await apfAuthPage.isPreviousButtonEnable(); - expect(is_prevButtonEnable).toBe(true); - }) test('test continue button is disable', async ({ page }) => { - apfAuthPage.movetoApfAuthPage() const is_ContinueButtonDisable = await apfAuthPage.isContinueButtonDisable(); - expect(is_ContinueButtonDisable).toBe(true); + await expect(is_ContinueButtonDisable).toBe(true); }) test('click view yaml button', async ({ page }) => { - apfAuthPage.movetoApfAuthPage() - apfAuthPage.viewYaml() + await apfAuthPage.viewYaml() await expect(apfAuthPage.editor_title_element).toBeTruthy(); - apfAuthPage.closeButton() + await apfAuthPage.closeButton() }) - test('test click skip APFAuth button', async ({ page }) => { - await apfAuthPage.movetoApfAuthPage() - const security_title = await apfAuthPage.click_skipApfAuth(); - expect(security_title).toBe(SECURITY_TITLE); - - }) - - test('Test view and submit button', async ({ page }) => { - apfAuthPage.movetoApfAuthPage() - apfAuthPage.click_viewAndSubmitJob() + test('Test view job output button', async ({ page }) => { + await apfAuthPage.click_viewAndSubmitJob() await expect(apfAuthPage.editor_title_element).toBeTruthy() - apfAuthPage.closeButton() + await apfAuthPage.closeButton() }) - test('Test view job', async ({ page }) => { - apfAuthPage.movetoApfAuthPage() - apfAuthPage.click_previewJob() - await expect(apfAuthPage.editor_title_element).toBeTruthy() - apfAuthPage.closeButton() - }) - test('Test save and close and Resume Progress', async ({ page }) => { - apfAuthPage.fillApfDetails(config.DATASET_PREFIX, config.AUTH_LOAD_LIB, config.AUTH_PLUGIN_LIB) - apfAuthPage.movetoApfAuthPage() apfAuthPage.click_saveAndClose() - titlePage.clickOnResumeProgress(); - const title = await securityPage.returnTitleOfSecurityPage(); - expect(title).toBe(SECURITY_TITLE); + await titlePage.clickOnResumeProgress(); + await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); + await connectionPage.SubmitValidateCredential() + const title = await apfAuthPage.returnTitleOfApfAuthPage(); + await expect(title).toBe(APF_AUTH_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(config.DATASET_PREFIX); - expect(authLoadLibValue).toBe(config.AUTH_LOAD_LIB); - expect(authPluginLibValue).toBe(config.AUTH_PLUGIN_LIB); + const AuthLoadLib_Value = await apfAuthPage.get_authLoadLib_value(); + const AuthPluginLib_Value = await apfAuthPage.get_authPluginLib_value(); + await expect(datatsetPrefixValue).toBe(config.DATASET_PREFIX); + await expect(AuthLoadLib_Value).toBe(config.AUTH_LOAD_LIB); + await expect(AuthPluginLib_Value).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 5b5071c1..9cd2c59b 100644 --- a/playwright_test/Tests/Connection.spec.ts +++ b/playwright_test/Tests/Connection.spec.ts @@ -12,6 +12,7 @@ const CONNECTION_PAGE_TITLE = 'Connection' const INSTALLATION_TITLE = 'Installation' test.beforeAll(async () => { + test.setTimeout(600000); try { await prepareEnvironment({ install: false, remove: false }); } catch (error) { @@ -53,7 +54,7 @@ test.describe('ConnectionTab', () => { }) test('test invalid credentials', async ({ page }) => { - await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); + await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, 'INVALID', 'INVALID_CRED'); await connectionPage.SubmitValidateCredential() const isGreenIconHidden = await connectionPage.isGreenCheckIconVisible(); expect(isGreenIconHidden).toBe(true); @@ -81,4 +82,4 @@ test.describe('ConnectionTab', () => { const isContinueButtonDisable = await connectionPage.isContinueButtonVisible(); expect(isContinueButtonDisable).toBe(true); }) -}) \ No newline at end of file +}) diff --git a/playwright_test/Tests/Installation.spec.ts b/playwright_test/Tests/Installation.spec.ts index 5fa352eb..bcc48b70 100644 --- a/playwright_test/Tests/Installation.spec.ts +++ b/playwright_test/Tests/Installation.spec.ts @@ -6,13 +6,27 @@ 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'; +import { prepareEnvironment } from '../prepare.js'; +import { connectArgs, Script } from '../setup'; + let electronApp: ElectronApplication const NETWORKING_PAGE_TITLE = 'Networking' const INSTALLATION_TYPE_TITLE = 'Installation'; const DOWNLOAD_ZOWE_TITLE = 'Download Zowe Pax'; +const ERROR_MSG ='One or more required dataset values are missing. Please ensure all fields are filled in.' +const script = new Script() +test.beforeAll(async () => { + test.setTimeout(600000); + try { + await prepareEnvironment({ install: true, cleanup:true, remove: false }); + } catch (error) { + console.error('Error during environment preparation:', error); + process.exit(1); + } +}); test.describe('InstallationTab', () => { let connectionPage: ConnectionPage; @@ -37,31 +51,29 @@ test.describe('InstallationTab', () => { titlePage.navigateToConnectionTab() 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, + await connectionPage.clickContinueButton(); + await planningPage.fillPlanningPageWithRequiredFields(config.ZOWE_ROOT_DIR, + config.ZOWE_WORKSPACE_DIR, + config.ZOWE_EXTENSION_DIR, + config.ZOWE_LOG_DIR, + 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 planningPage.clickValidateLocations() + await planningPage.clickContinueToInstallation() + await installationTypePage.downloadZowePaxAndNavigateToInstallationPage() + await installationTypePage.clickOnContinueToUnpax() + await installationTypePage.skipUnpax() }) test.afterEach(async () => { await electronApp.close() }) + test('Test all required fields on Installation page', async ({ page }) => { expect(installationPage.prefix).toBeTruthy() expect(installationPage.procLib).toBeTruthy() @@ -79,8 +91,8 @@ test.describe('InstallationTab', () => { expect(installationPage.previousStep).toBeTruthy() expect(installationPage.skipInstallation).toBeTruthy() expect(installationPage.clickContinueToNetworkSetup).toBeTruthy() - const is_Continue_Button_disable = await installationPage.isContinueToNetworkSetupEnabled(); - expect(is_Continue_Button_disable).toBe(true); + const isContinueButtonEnabled = await installationPage.isContinueToNetworkSetupEnabled(); + expect(isContinueButtonEnabled).toBe(false); }) test('Test Installation with Valid Data with Download Pax', async ({ page }) => { @@ -101,15 +113,16 @@ test.describe('InstallationTab', () => { }) test('Test Installation with the Invalid Data', async ({ page }) => { - await installationPage.enterPrefix('DSPREFID') + await installationPage.enterPrefix('^&*(^$') await installationPage.enterProcLib('') - await installationPage.enterParmLib('test') + 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 ErrorMsgOnEmpyFields = await installationPage.getErrorMsg(); + expect(ErrorMsgOnEmpyFields).toBe(ERROR_MSG); const is_Continue_Button_enable = await installationPage.isContinueToNetworkSetupEnabled(); expect(is_Continue_Button_enable).toBe(false); }) @@ -140,6 +153,47 @@ test.describe('InstallationTab', () => { expect(installationPage.editorTitleElement).toBeTruthy(); await installationPage.clickCloseEditor() }) + + + test('verify yaml updated on zos correctly', async ({ page }) => { + 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 result = await script.runCommand(`cat ${process.env.ZOWE_ROOT_DIR}/zowe.yaml`); + await expect(result.details).toContain(config.DATASET_PREFIX); + await expect(result.details).toContain(config.PARM_LIB); + await expect(result.details).toContain(config.PROC_LIB); + await expect(result.details).toContain(config.JCL_LIB); + await expect(result.details).toContain(config.LOAD_LIB); + await expect(result.details).toContain(config.AUTH_LOAD_LIB); + await expect(result.details).toContain(config.AUTH_PLUGIN_LIB); + }); + + test('Verify MVS dataset was successfully created on z/OS.', async ({ page }) => { + 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 result = await script.runCommand(`tso "LISTCAT"`); + + await expect(result.details).toContain(config.DATASET_PREFIX); + await expect(result.details).toContain(config.PARM_LIB); + await expect(result.details).toContain(config.JCL_LIB); + await expect(result.details).toContain(config.LOAD_LIB); + await expect(result.details).toContain(config.AUTH_LOAD_LIB); + await expect(result.details).toContain(config.AUTH_PLUGIN_LIB); + }); test('Test Save and Close and Resume Progress', async ({page}) => { await installationPage.fillAllFields(config.DATASET_PREFIX, @@ -165,4 +219,4 @@ test.describe('InstallationTab', () => { 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 80a67e1e..6bae3d29 100644 --- a/playwright_test/Tests/InstallationType.spec.ts +++ b/playwright_test/Tests/InstallationType.spec.ts @@ -5,12 +5,23 @@ 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'; +import { prepareEnvironment } from '../prepare.js'; + let electronApp: ElectronApplication const PLANNING_TITLE = 'Before you start'; const INSTALLATION_PAGE_TITLE = 'Installation'; const DOWNLOAD_ZOWE_PAX = 'Download Zowe Pax'; +test.beforeAll(async () => { + test.setTimeout(600000); + try { + await prepareEnvironment({ install: true, remove: false }); + } catch (error) { + console.error('Error during environment preparation:', error); + process.exit(1); + } +}); test.describe('InstallationTypeTab', () => { let connectionPage: ConnectionPage; @@ -28,21 +39,18 @@ test.describe('InstallationTypeTab', () => { planningPage = new PlanningPage(page); installationTypePage = new InstallationTypePage(page); installationPage = new InstallationPage(page); - titlePage.navigateToConnectionTab() + await titlePage.navigateToConnectionTab() await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); - await connectionPage.SubmitValidateCredential(); - await connectionPage.clickContinueButton(); + 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.ZOWE_WORKSPACE_DIR, + config.ZOWE_EXTENSION_DIR, + config.ZOWE_LOG_DIR, + config.JAVA_HOME, + config.NODE_HOME, + config.ZOSMF_HOST, + config.ZOSMF_PORT, config.ZOSMF_APP_ID ); await planningPage.clickValidateLocations() @@ -100,7 +108,7 @@ test.describe('InstallationTypeTab', () => { await installationTypePage.clickAgreeLicense() const Is_Continue_Button_Enable = await installationTypePage.isContinueUnpaxEnabled(); expect(Is_Continue_Button_Enable).toBe(true); - await installationTypePage.continueToUnpax() + await installationTypePage.clickOnContinueToUnpax() const title = await installationPage.getInstallationPageTitle(); expect(title).toBe(DOWNLOAD_ZOWE_PAX); }) @@ -113,10 +121,11 @@ test.describe('InstallationTypeTab', () => { expect(Is_Continue_Button_Enable).toBe(true); await installationTypePage.clickSaveAndClose(); await titlePage.clickOnResumeProgress(); - await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); + await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); + await connectionPage.SubmitValidateCredential() const is_GreenCheck_Visible = await installationTypePage.isLicenseAgreementGreenCheckVisible(); expect(is_GreenCheck_Visible).toBe(true); 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/LaunchConfig.spec.ts b/playwright_test/Tests/LaunchConfig.spec.ts index 64980867..204d4e79 100644 --- a/playwright_test/Tests/LaunchConfig.spec.ts +++ b/playwright_test/Tests/LaunchConfig.spec.ts @@ -1,35 +1,34 @@ import { test, ElectronApplication, expect, _electron as electron } from '@playwright/test'; +import config from '../utils/config'; import { prepareEnvironment } from '../prepare.js'; -import TitlePage from '../Pages/title.page'; -import ConnectionPage from '../Pages/connection.page'; -import PlanningPage from '../Pages/planning.page'; +import TitlePage from '../Pages/title.page.ts'; +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 NetworkingPage from '../Pages/networking.page.ts'; +import SecurityPage from '../Pages/security.page.ts' +import StcsPage from '../Pages/stcs.page.ts' +import ApfAuthPage from '../Pages/ApfAuth.page'; +import VsamPage from '../Pages/Vsam.page'; import LaunchConfigPage from '../Pages/launchConfig.page'; import { spawn } from 'child_process'; import path from 'path'; +import { connectArgs, Script } from '../setup'; let page: Page; let electronApp: ElectronApplication const CONFPAGE_TITLE = 'Configuration' -const CERTIFICATE_TITLE = 'Certificates' +const CACHINGSERVICE_TITLE = 'CachingService' +const REVIEWPAGE_TITLE = 'Review Installation' const VALIDATION_ERROR_MSG = 'is a required property' -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 script = new Script() + + test.beforeAll(async () => { + test.setTimeout(600000); try { await prepareEnvironment({ install: true, remove: false }); } catch (error) { @@ -39,43 +38,74 @@ test.beforeAll(async () => { }); test.describe('launchConfigTab', () => { - let connectionPage: ConnectionPage; - let titlePage : TitlePage; - let planningPage : PlanningPage; - let launchConfigPage : LaunchConfigPage; + let connectionPage: ConnectionPage; + let titlePage : TitlePage; + let installationTypePage : InstallationTypePage; + let planningPage : PlanningPage; + let installationPage : InstallationPage; + let networkingPage : NetworkingPage + let stcsPage : StcsPage + let securityPage : SecurityPage + let apfAuthPage : ApfAuthPage; + let vsamPage : VsamPage; + let launchConfigPage : LaunchConfigPage; + test.beforeEach(async ({ page }) => { - test.setTimeout(900000); - electronApp = await electron.launch({ args: ['.webpack/main/index.js'] }) - page= await electronApp.firstWindow() - connectionPage = new ConnectionPage(page); - launchConfigPage = new LaunchConfigPage(page); - titlePage = new TitlePage(page); - planningPage = new PlanningPage(page); - titlePage.navigateToConnectionTab() - connectionPage.fillConnectionDetails(SSH_HOST,SSH_PORT,SSH_USER,SSH_PASSWD) - connectionPage.SubmitValidateCredential() - await page.waitForTimeout(5000); - connectionPage.clickContinueButton() - 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); - launchConfigPage.movetoLaunchConfigPage() - await page.waitForTimeout(5000); + test.setTimeout(900000); + electronApp = await electron.launch({ args: ['.webpack/main/index.js'] }) + page= await electronApp.firstWindow() + connectionPage = new ConnectionPage(page); + launchConfigPage = new LaunchConfigPage(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); + securityPage = new SecurityPage(page); + stcsPage = new StcsPage(page); + vsamPage = new VsamPage(page); + await titlePage.navigateToConnectionTab() + 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, + 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.clickOnContinueToUnpax() + 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 launchConfigPage.movetoLaunchConfigPage(); }) test.afterEach(async () => { await electronApp.close() }) - test('test title of page', async ({ page }) => { - await page.waitForTimeout(5000); - const title = await launchConfigPage.returnTitleOfConfPage(); - expect(title).toBe(CONFPAGE_TITLE); + test('test title of page', async ({ page }) => { + await page.waitForTimeout(5000); + const title = await launchConfigPage.returnTitleOfConfPage(); + expect(title).toBe(CONFPAGE_TITLE); }) test('test all required fields', async ({ page }) => { @@ -100,7 +130,6 @@ test.describe('launchConfigTab', () => { } }) - test('test select log level', async ({ page }) => { await page.waitForTimeout(5000); const values = ['info', 'debug', 'trace']; @@ -112,55 +141,42 @@ test.describe('launchConfigTab', () => { } }) + test('Test Skip launch config button is enable', async ({ page }) => { + const isLaunchConfigEnable = await launchConfigPage.is_skipLaunchConfigButtonEnable(); + expect(isLaunchConfigEnable).toBe(true); + const title = await launchConfigPage.click_skipLaunhConfig(); + expect(title).toBe(REVIEWPAGE_TITLE); + }) + test('test select component configure', async ({ page }) => { - await page.waitForTimeout(5000); const values = ['warn', 'exit']; for (const value of values) { await launchConfigPage.fillvaluescomponentConfig(value); - await page.waitForTimeout(5000); const componentConfigValue = await launchConfigPage.get_componentConfig_value(); expect(componentConfigValue).toBe(value); } }) + test('Test view yaml button', async ({ page }) => { - await page.waitForTimeout(7000); - launchConfigPage.viewYaml() - await page.waitForTimeout(5000); + await launchConfigPage.viewYaml() await expect(launchConfigPage.editor_title_element).toBeTruthy(); - await page.waitForTimeout(5000); - launchConfigPage.closeButton() - await page.waitForTimeout(2000); - }) - - test('Test view and submit button', async ({ page }) => { - await page.waitForTimeout(5000); - launchConfigPage.click_viewAndSubmitJob() - await page.waitForTimeout(5000); - await expect(launchConfigPage.editor_title_element).toBeTruthy() - launchConfigPage.closeButton() - await page.waitForTimeout(2000); + await launchConfigPage.closeButton() }) - - test('Test view job', async ({ page }) => { - await page.waitForTimeout(5000); - launchConfigPage.click_previewJob() - await page.waitForTimeout(5000); + test('Test view job output button', async ({ page }) => { + await launchConfigPage.click_viewJobOutput() await expect(launchConfigPage.editor_title_element).toBeTruthy() - launchConfigPage.closeButton() - await page.waitForTimeout(5000); + await launchConfigPage.closeButton() }) test('Test save and close and Resume Progress', async ({ page }) => { - await page.waitForTimeout(5000); - launchConfigPage.fillvalues('STRICT') - launchConfigPage.fillvalues_logLevel('info') - launchConfigPage.fillvaluescomponentConfig('warn') - await page.waitForTimeout(5000); - launchConfigPage.click_saveAndClose() - await page.waitForTimeout(3000); - titlePage.clickOnResumeProgress(); - await page.waitForTimeout(15000); + await launchConfigPage.fillvalues('STRICT'); + await launchConfigPage.fillvalues_logLevel('info'); + await launchConfigPage.fillvaluescomponentConfig('warn'); + await launchConfigPage.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 launchConfigPage.returnTitleOfConfPage(); expect(title).toBe(CONFPAGE_TITLE); const Validation_Value = await launchConfigPage.get_validation_value(); @@ -169,57 +185,41 @@ test.describe('launchConfigTab', () => { expect(Validation_Value).toBe('STRICT'); expect(LogLevel_Value).toBe('info'); expect(ComponentConfig_Value).toBe('warn'); - }) + }); - test('click Previous step button', async ({ page }) => { - await page.waitForTimeout(5000); - const title = await launchConfigPage.returnTitleOfPrevPage(); - expect(title).toBe(CERTIFICATE_TITLE); - }) - test('Test previous button is enabled', async ({ page }) => { + test('click and verify Previous step button is enabled', async ({ page }) => { const is_prevButtonEnable = await launchConfigPage.isPreviousButtonEnable(); expect(is_prevButtonEnable).toBe(true); - await page.waitForTimeout(2000); - }) - - test('Test continue to review button is disable', async ({ page }) => { - await page.waitForTimeout(2000); - const is_ContinueButtonDisable = await launchConfigPage.isContinueButtonDisable(); - expect(is_ContinueButtonDisable).toBe(true); - await page.waitForTimeout(2000); - }) - - test('Test Skip launch config button is enable', async ({ page }) => { - await page.waitForTimeout(2000); - const isLaunchConfigEnable = await launchConfigPage.is_skipLaunchConfigButtonEnable(); - expect(isLaunchConfigEnable).toBe(true); - await page.waitForTimeout(2000); + const title = await launchConfigPage.returnTitleOfPrevPage(); + expect(title).toBe(CACHINGSERVICE_TITLE); }) test('Test yaml should be updated', async ({ page }) => { - await page.waitForTimeout(5000); await launchConfigPage.fillvalues('STRICT'); - await page.waitForTimeout(5000); await launchConfigPage.fillvalues_logLevel('info'); - await page.waitForTimeout(5000); await launchConfigPage.fillvaluescomponentConfig('warn'); - await page.waitForTimeout(15000); await launchConfigPage.viewYaml(); - await page.waitForTimeout(10000); await expect(launchConfigPage.editor_title_element).toBeTruthy(); - await page.waitForTimeout(5000); const yaml = await launchConfigPage.read_yaml(); - await page.waitForTimeout(5000); - expect(yaml).toContain('info'); - expect(yaml).toContain('STRICT'); - expect(yaml).toContain('warn'); + console.log(yaml) + expect(yaml).toContain('logLevel: info'); + expect(yaml).toContain('validation: STRICT'); + expect(yaml).toContain('onComponentConfigureFail: warn'); }) test('Test keep mandatory field empty', async ({ page }) => { - await page.waitForTimeout(5000); await launchConfigPage.fillvalues(''); - await page.waitForTimeout(5000); const Errormsg = await launchConfigPage.get_validation_error_msg(); - expect(Errormsg).expect(VALIDATION_ERROR_MSG); + expect(Errormsg).toBe(VALIDATION_ERROR_MSG); }) + + test('verify yaml updated on zos correctly', async ({ page }) => { + await launchConfigPage.fillvalues('STRICT'); + await launchConfigPage.fillvalues_logLevel('info'); + await launchConfigPage.fillvaluescomponentConfig('warn'); + const result = await script.runCommand(`cat ${process.env.ZOWE_ROOT_DIR}/zowe.yaml`); + await expect(result.details).toContain('STRICT'); + await expect(result.details).toContain('info'); + await expect(result.details).toContain('warn'); + }); }); diff --git a/playwright_test/Tests/Networking.spec.ts b/playwright_test/Tests/Networking.spec.ts index 55202448..10ca6f21 100644 --- a/playwright_test/Tests/Networking.spec.ts +++ b/playwright_test/Tests/Networking.spec.ts @@ -10,6 +10,8 @@ import PlanningPage from '../Pages/planning.page'; import NetworkingPage from '../Pages/networking.page'; import path from 'path'; import config from '../utils/config'; +import { connectArgs, Script } from '../setup'; + let page: Page; @@ -17,9 +19,12 @@ let electronApp: ElectronApplication const NETWORKING_TITLE = 'Networking'; const APFAUTH_TITLE = 'APF Authorize Load Libraries'; const INSTALLATION_TITLE = 'Installation'; +const script = new Script() + test.beforeAll(async () => { + test.setTimeout(600000); try { await prepareEnvironment({ install: true, remove: false }); } catch (error) { @@ -34,8 +39,8 @@ test.describe('networkingTab', () => { let securityPage : SecurityPage; let planningPage : PlanningPage; let networkingPage : NetworkingPage; - let installationTypePage : InstallationTypePage; - let installationPage : InstallationPage; + let installationTypePage : InstallationTypePage; + let installationPage : InstallationPage; test.beforeEach(async ({ page }) => { test.setTimeout(900000); @@ -45,29 +50,26 @@ test.describe('networkingTab', () => { networkingPage = new NetworkingPage(page); titlePage = new TitlePage(page); planningPage = new PlanningPage(page); - installationPage = new InstallationPage(page); - installationTypePage = new InstallationTypePage(page); - titlePage.navigateToConnectionTab() + installationPage = new InstallationPage(page); + installationTypePage = new InstallationTypePage(page); + await titlePage.navigateToConnectionTab() 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 connectionPage.SubmitValidateCredential(); + await connectionPage.clickContinueButton(); + await planningPage.fillPlanningPageWithRequiredFields(config.ZOWE_ROOT_DIR, + config.ZOWE_WORKSPACE_DIR, + config.ZOWE_EXTENSION_DIR, + config.ZOWE_LOG_DIR, + 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.clickOnContinueToUnpax() await installationTypePage.skipUnpax() await installationPage.fillAllFields(config.DATASET_PREFIX, config.PARM_LIB, @@ -77,8 +79,8 @@ test.describe('networkingTab', () => { config.AUTH_LOAD_LIB, config.AUTH_PLUGIN_LIB ) - await installationPage.clickInstallMvsDatasets(); - await installationPage.clickContinueToNetworkSetup(); + await installationPage.clickInstallMvsDatasets(); + await installationPage.clickContinueToNetworkSetup(); }) test.afterEach(async () => { @@ -110,12 +112,15 @@ test.describe('networkingTab', () => { await expect(networkingPage.discovery).toBeTruthy() }) - test('test external domain field', async ({ page }) => { + test('test external domain field & verify value updated on yaml', async ({ page }) => { await networkingPage.fillexternal_domainvalues(config.DOMAIN_NAME, config.EXTERNAL_PORT); const port = await networkingPage.get_externalDomainport_value(); const domainName = await networkingPage.get_externalDomainName_value(); expect(port).toBe(config.EXTERNAL_PORT); expect(domainName).toBe(config.DOMAIN_NAME); + const result = await script.runCommand(`cat ${process.env.ZOWE_ROOT_DIR}/zowe.yaml`); + await expect(result.details).toContain(config.EXTERNAL_PORT); + await expect(result.details).toContain(config.DOMAIN_NAME); }) test('test deleting domain name field', async ({ page }) => { @@ -136,15 +141,64 @@ test.describe('networkingTab', () => { expect(newValue).toBe(originalValue); }) - 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 debug checkbox functionality across all components', async ({ page }) => { + const after_click_metric = await networkingPage.isCheckBoxChecked('metrics-service','debug'); + const after_click_gateway = await networkingPage.isCheckBoxChecked('gateway','debug'); + const after_click_zaas = await networkingPage.isCheckBoxChecked('zaas','debug'); + const after_click_apicatalog = await networkingPage.isCheckBoxChecked('api-catalog','debug'); + const after_click_discovery = await networkingPage.isCheckBoxChecked('discovery','debug'); + const after_click_caching = await networkingPage.isCheckBoxChecked('caching-service','debug'); + const after_click_appServer = await networkingPage.isCheckBoxChecked('app-server','debug'); + const after_click_zss = await networkingPage.isCheckBoxChecked('zss','tls'); + const after_click_jobsApi = await networkingPage.isCheckBoxChecked('jobs-api','debug'); + const after_click_filesApi = await networkingPage.isCheckBoxChecked('files-api','debug'); + const after_click_cloudGateway = await networkingPage.isCheckBoxChecked('cloud-gateway','debug'); + expect(after_click_metric).toBe(true); + expect(after_click_gateway).toBe(true); + expect(after_click_zaas).toBe(true); + expect(after_click_apicatalog).toBe(true); + expect(after_click_discovery).toBe(true); + expect(after_click_caching).toBe(true); + expect(after_click_appServer).toBe(true); + expect(after_click_zss).toBe(true); + expect(after_click_jobsApi).toBe(true); + expect(after_click_filesApi).toBe(true); + expect(after_click_cloudGateway).toBe(true); + }) + + test('Test enabled checkbox functionality across all components', async ({ page }) => { + const after_click_metric = await networkingPage.isCheckBoxChecked('metrics-service','enabled'); + const after_click_gateway = await networkingPage.isCheckBoxChecked('gateway','enabled'); + const after_click_zaas = await networkingPage.isCheckBoxChecked('zaas','enabled'); + const after_click_apicatalog = await networkingPage.isCheckBoxChecked('api-catalog','enabled'); + const after_click_discovery = await networkingPage.isCheckBoxChecked('discovery','enabled'); + const after_click_caching = await networkingPage.isCheckBoxChecked('caching-service','enabled'); + const after_click_appServer = await networkingPage.isCheckBoxChecked('app-server','enabled'); + const after_click_zss = await networkingPage.isCheckBoxChecked('zss','enabled'); + const after_click_jobsApi = await networkingPage.isCheckBoxChecked('jobs-api','enabled'); + const after_click_filesApi = await networkingPage.isCheckBoxChecked('files-api','enabled'); + const after_click_cloudGateway = await networkingPage.isCheckBoxChecked('cloud-gateway','enabled'); + const after_click_explorerJes = await networkingPage.isCheckBoxChecked('explorer-jes','enabled'); + const after_click_explorerMvs = await networkingPage.isCheckBoxChecked('explorer-mvs','enabled'); + const after_click_explorerUss = await networkingPage.isCheckBoxChecked('explorer-uss','enabled'); + expect(after_click_metric).toBe(true); + expect(after_click_gateway).toBe(true); + expect(after_click_zaas).toBe(true); + expect(after_click_apicatalog).toBe(true); + expect(after_click_discovery).toBe(true); + expect(after_click_caching).toBe(true); + expect(after_click_appServer).toBe(true); + expect(after_click_zss).toBe(true); + expect(after_click_jobsApi).toBe(true); + expect(after_click_filesApi).toBe(true); + expect(after_click_cloudGateway).toBe(true); + expect(after_click_explorerJes).toBe(true); + expect(after_click_explorerMvs).toBe(true); + expect(after_click_explorerUss).toBe(true); + }) test('Test view yaml button', async ({ page }) => { + await page.waitForTimeout(5000); await networkingPage.viewYaml() await expect(networkingPage.editor_title_element).toBeTruthy(); await networkingPage.closeButton() @@ -155,8 +209,8 @@ test.describe('networkingTab', () => { 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(); + 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(); diff --git a/playwright_test/Tests/Planning.spec.ts b/playwright_test/Tests/Planning.spec.ts index f05de8d6..5007d065 100644 --- a/playwright_test/Tests/Planning.spec.ts +++ b/playwright_test/Tests/Planning.spec.ts @@ -12,8 +12,9 @@ const CONNECTION_PAGE_TITLE = 'Connection'; const PLANNING_TITLE = 'Before you start'; const INSTALLATION_TYPE_TITLE = 'Installation Type'; const INVALID_JOB_STATEMENT = "//HELLOJOB JOB 'HELLO, WORLD!',CLASS=A,MSGCLASS"; -const ERROR_MESSAGE = "Failed to verify job statement STMT NO. MESSAGE\n 1 IEFC006I POSITIONAL PARAMETERS MUST BE SPECIFIED BEFORE KEYWORD PARAMETERS"; +const ERROR_MESSAGE = `Failed to verify job statement STMT NO. MESSAGE\r\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"; +const INVALID_INPUT_ERROR = 'Test/DIR is not a valid z/OS Unix path' test.describe('PlanningTab', () => { let connectionPage: ConnectionPage; @@ -31,21 +32,14 @@ test.describe('PlanningTab', () => { installationTypePage = new InstallationTypePage(page); titlePage.navigateToConnectionTab(); await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); - await connectionPage.SubmitValidateCredential(); - await connectionPage.clickContinueButton(); + await connectionPage.SubmitValidateCredential(); + await connectionPage.clickContinueButton(); }) test.afterEach(async () => { await electronApp.close() }) - test('Test all required fields on Planning Tab', async () => { - expect(planningPage.planningPageTitle).toBeTruthy(); - expect(planningPage.zoweInstallationLink).toBeTruthy(); - expect(planningPage.jobStatement).toBeTruthy(); - expect(planningPage.saveAndValidate).toBeTruthy(); - }) - test('Test Valid Job Statement and Save Validate', async () => { await planningPage.clickSaveValidate(); const isGreen_check_visible = await planningPage.isSaveAndValidateGreenCheckVisible(); @@ -54,9 +48,9 @@ test.describe('PlanningTab', () => { test('Test Invalid Job Statement and Save Validate', async () => { await planningPage.enterJobStatement(INVALID_JOB_STATEMENT); - await planningPage.clickSaveAndValidate(); + await planningPage.clickSaveAndValidate(); const error_Message = await planningPage.getErrorMessage() - expect (error_Message).toBe(ERROR_MESSAGE); + expect (error_Message.trim()).toBe(ERROR_MESSAGE.trim()); const isGreen_check_visible = await planningPage.isSaveAndValidateGreenCheckVisible(); expect(isGreen_check_visible).toBe(false); }) @@ -88,7 +82,7 @@ test.describe('PlanningTab', () => { expect(planningPage.zosmfPort).toBeTruthy(); expect(planningPage.zosmfApplicationId).toBeTruthy(); expect(planningPage.validateLocations).toBeTruthy(); - expect(planningPage.saveAndClose).toBeTruthy(); + expect(planningPage.save_and_close).toBeTruthy(); expect(planningPage.previousStep).toBeTruthy(); expect(planningPage.continueInstallationOptions).toBeTruthy(); const is_Continue_Button_disable = await planningPage.isContinueToInstallationDisabled(); @@ -97,19 +91,16 @@ test.describe('PlanningTab', () => { test('Test Validate Locations with Valid Data', async () => { 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.ZOWE_WORKSPACE_DIR, + config.ZOWE_EXTENSION_DIR, + config.ZOWE_LOG_DIR, + config.JAVA_HOME, + config.NODE_HOME, + config.ZOSMF_HOST, + config.ZOSMF_PORT, config.ZOSMF_APP_ID ); - await planningPage.clickValidateLocations() + await planningPage.clickValidateLocations() const is_GreenCheck_Visible = await planningPage.isValidateLocationsGreenCheckVisible(); expect(is_GreenCheck_Visible).toBe(true); const is_Continue_Button_enable = await planningPage.isContinueToInstallationEnabled(); @@ -125,45 +116,33 @@ test.describe('PlanningTab', () => { 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(); - expect(is_Continue_Button_enable).toBe(false); + const error_Message = await planningPage.getErrorMessage() + expect (error_Message).toBe(INVALID_INPUT_ERROR); + const is_Continue_Button_enable = await planningPage.isContinueToInstallationDisabled(); + expect(is_Continue_Button_enable).toBe(true); }) + - test('Test Previous step', async ({ page }) => { - await planningPage.clickPreviousStep(); - const title = await connectionPage.getConnectionPageTitle(); - expect(title).toBe(CONNECTION_PAGE_TITLE); - }) - - test('Test Save and Close and Resume Progress', async () => { - 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(); + test('Test Save and Close and Resume Progress', async () => { + await planningPage.fillPlanningPageWithRequiredFields(config.ZOWE_ROOT_DIR, + config.ZOWE_WORKSPACE_DIR, + config.ZOWE_EXTENSION_DIR, + config.ZOWE_LOG_DIR, + config.JAVA_HOME, + config.NODE_HOME, + config.ZOSMF_HOST, + config.ZOSMF_PORT, + config.ZOSMF_APP_ID + ); + await planningPage.clickValidateLocations() + await planningPage.click_saveAndClose() await titlePage.clickOnResumeProgress(); - await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); - await connectionPage.SubmitValidateCredential(); + 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 3a296d04..3092ae1c 100644 --- a/playwright_test/Tests/Security.spec.ts +++ b/playwright_test/Tests/Security.spec.ts @@ -10,6 +10,7 @@ import InstallationPage from '../Pages/installation.page.ts'; import InstallationTypePage from '../Pages/installationType.page.ts'; import path from 'path'; import config from '../utils/config'; +import { connectArgs, Script } from '../setup'; let page: Page; @@ -18,9 +19,12 @@ const CERTIFICATE_TITLE = 'Certificates' const SECURITY_TITLE = 'Security' const APF_AUTH_TITLE ='APF Authorize Load Libraries' const STC_TITTLE = 'Stcs' +const script = new Script() + test.beforeAll(async () => { + test.setTimeout(600000); try { await prepareEnvironment({ install: true, remove: false }); } catch (error) { @@ -35,9 +39,9 @@ test.describe('securityTab', () => { let securityPage : SecurityPage; let planningPage : PlanningPage; let apfAuthPage : ApfAuthPage; - let networkingPage : NetworkingPage; - let installationTypePage : InstallationTypePage; - let installationPage : InstallationPage; + let networkingPage : NetworkingPage; + let installationTypePage : InstallationTypePage; + let installationPage : InstallationPage; test.beforeEach(async ({ page }) => { @@ -47,122 +51,138 @@ test.describe('securityTab', () => { connectionPage = new ConnectionPage(page); titlePage = new TitlePage(page); planningPage = new PlanningPage(page); - networkingPage = new NetworkingPage(page); + networkingPage = new NetworkingPage(page); apfAuthPage = new ApfAuthPage(page); securityPage = new SecurityPage(page); - installationPage = new InstallationPage(page); - installationTypePage = new InstallationTypePage(page); + installationPage = new InstallationPage(page); + installationTypePage = new InstallationTypePage(page); titlePage.navigateToConnectionTab() 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.fillPlanningPageWithRequiredFields(config.ZOWE_ROOT_DIR, + config.ZOWE_WORKSPACE_DIR, + config.ZOWE_EXTENSION_DIR, + config.ZOWE_LOG_DIR, + 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() + await installationTypePage.downloadZowePaxAndNavigateToInstallationPage() + await installationTypePage.clickOnContinueToUnpax() + 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 securityPage.movetoSecurityPage() }) test.afterEach(async () => { await electronApp.close() }) - test('Test all required fields on security page', async ({ page }) => { - await expect(securityPage.product).toBeTruthy() - await expect(securityPage.admin).toBeTruthy() - await expect(securityPage.stc).toBeTruthy() - await expect(securityPage.sys_prog).toBeTruthy() - await expect(securityPage.user_zis).toBeTruthy() - await expect(securityPage.user_zowe).toBeTruthy() - await expect(securityPage.aux).toBeTruthy() - await expect(securityPage.stc_zowe).toBeTruthy() - await expect(securityPage.stc_zis).toBeTruthy() - await expect(securityPage.view_yaml).toBeTruthy() - await expect(securityPage.save_and_close).toBeTruthy() - await expect(securityPage.previous_step).toBeTruthy() - await expect(securityPage.skip_button).toBeTruthy() - await expect(securityPage.continue_CertificateSelector).toBeTruthy() - - }) - //needs to be done - test('test security with valid data', async ({ page }) => { - 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 }) => { - 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 }) => { - 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 all required fields on security page', async ({ page }) => { + await expect(securityPage.product).toBeTruthy() + await expect(securityPage.admin).toBeTruthy() + await expect(securityPage.stc).toBeTruthy() + await expect(securityPage.sys_prog).toBeTruthy() + await expect(securityPage.user_zis).toBeTruthy() + await expect(securityPage.user_zowe).toBeTruthy() + await expect(securityPage.aux).toBeTruthy() + await expect(securityPage.stc_zowe).toBeTruthy() + await expect(securityPage.stc_zis).toBeTruthy() + await expect(securityPage.view_yaml).toBeTruthy() + await expect(securityPage.save_and_close).toBeTruthy() + await expect(securityPage.previous_step).toBeTruthy() + await expect(securityPage.skip_button).toBeTruthy() + await expect(securityPage.continue_CertificateSelector).toBeTruthy() + }) - test('Test continue to certificate button is disable', async ({ page }) => { - const is_ContinueButtonDisable = await securityPage.isContinueButtonDisable(); - expect(is_ContinueButtonDisable).toBe(true); + test('test security with valid data', async ({ page }) => { + 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('Test view yaml button', async ({ page }) => { - await securityPage.viewYaml() - await expect(securityPage.editor_title_element).toBeTruthy(); - await securityPage.closeButton() - }) + test('click Previous step button', async ({ page }) => { + 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 }) => { + 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 view job output', async ({ page }) => { - await securityPage.click_viewAndSubmitJob() - await expect(securityPage.editor_title_element).toBeTruthy() - await securityPage.closeButton() - }) - test('Test save and close and Resume Progress', async ({ page }) => { + test('Test continue to certificate button is disable', async ({ page }) => { + const is_ContinueButtonDisable = await securityPage.isContinueButtonDisable(); + expect(is_ContinueButtonDisable).toBe(true); + }) + + test('Test view yaml button', async ({ page }) => { + await securityPage.viewYaml() + await expect(securityPage.editor_title_element).toBeTruthy(); + await securityPage.closeButton() + }) + + test('Test view job output', async ({ page }) => { + await securityPage.click_viewAndSubmitJob() + await expect(securityPage.editor_title_element).toBeTruthy() + await securityPage.closeButton() + }) + + test('verify yaml updated on zos correctly', async ({ page }) => { + 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 result = await script.runCommand(`cat ${process.env.ZOWE_ROOT_DIR}/zowe.yaml`); + await expect(result.details).toContain(config.SECURITY_ADMIN); + await expect(result.details).toContain(config.SECURITY_STC); + await expect(result.details).toContain(config.SECURITY_SYSPROG); + await expect(result.details).toContain(config.SECURITY_USER_ZIS); + await expect(result.details).toContain(config.SECURITY_USER_ZOWE); + await expect(result.details).toContain(config.SECURITY_AUX); + await expect(result.details).toContain(config.SECURITY_STC_ZOWE); + await expect(result.details).toContain(config.SECURITY_STC_ZIS); + }); + + test('Test save and close and Resume Progress', async ({ page }) => { await securityPage.fillSecurityDetails('RACF', config.SECURITY_ADMIN, config.SECURITY_STC, @@ -173,9 +193,9 @@ test.describe('securityTab', () => { config.SECURITY_STC_ZOWE, config.SECURITY_STC_ZIS ) - await securityPage.click_saveAndClose() + await securityPage.click_saveAndClose() await titlePage.clickOnResumeProgress(); - await connectionPage.fillConnectionDetails(config.SSH_HOST, config.SSH_PORT, config.SSH_USER, config.SSH_PASSWD); + 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); @@ -196,4 +216,6 @@ test.describe('securityTab', () => { expect(stcZis_value).toBe(process.env.SECURITY_STC_ZIS); expect(aux_value).toBe(process.env.SECURITY_AUX); }) -}) \ No newline at end of file +}) + + diff --git a/playwright_test/Tests/Stcs.spec.ts b/playwright_test/Tests/Stcs.spec.ts new file mode 100644 index 00000000..74891c0d --- /dev/null +++ b/playwright_test/Tests/Stcs.spec.ts @@ -0,0 +1,211 @@ +import { test, ElectronApplication, expect, _electron as electron } from '@playwright/test'; +import { prepareEnvironment } from '../prepare.js'; +import TitlePage from '../Pages/title.page.ts'; +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 NetworkingPage from '../Pages/networking.page.ts'; +import SecurityPage from '../Pages/security.page.ts' +import StcsPage from '../Pages/stcs.page.ts' +import config from '../utils/config'; +import ApfAuthPage from '../Pages/ApfAuth.page'; +import { connectArgs, Script } from '../setup'; + + +let electronApp: ElectronApplication +const STCS_TITLE = 'Stcs' +const SECURITY_TITLE = 'Security'; +const CERTIFICATE_TITLE = 'Certificates' +const script = new Script(); + +test.beforeAll(async () => { + test.setTimeout(600000); + try { + await prepareEnvironment({ install: true, cleanup:true, remove: false }); + } catch (error) { + console.error('Error during environment preparation:', error); + process.exit(1); + } +}); + +test.describe('StcsTab', () => { + let connectionPage: ConnectionPage; + let titlePage : TitlePage; + let installationTypePage : InstallationTypePage; + let planningPage : PlanningPage; + let installationPage : InstallationPage; + let networkingPage : NetworkingPage + let stcsPage : StcsPage + let securityPage : SecurityPage + let apfAuthPage : ApfAuthPage; + + + + test.beforeEach(async ({ page }) => { + test.setTimeout(900000); + electronApp = await electron.launch({ args: ['.webpack/main/index.js'] }) + 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); + securityPage = new SecurityPage(page); + stcsPage = new StcsPage(page); + titlePage.navigateToConnectionTab() + 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, + 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.clickOnContinueToUnpax() + 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 page.waitForTimeout(2000); + await installationPage.clickContinueToNetworkSetup(); + await networkingPage.click_skipNetworking() + await apfAuthPage.click_skipApfAuth() + await page.waitForTimeout(20000); + 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 stcsPage.movetoStcsPage() + }) + + test.afterEach(async () => { + await electronApp.close() + }) + + + test('test title and required fields of page', async ({ page }) => { + const title = await stcsPage.returnTitleOfStcsPage(); + expect(title).toBe(STCS_TITLE); + await expect(stcsPage.zis).toBeTruthy() + await expect(stcsPage.zowe).toBeTruthy() + await expect(stcsPage.aux).toBeTruthy() + await expect(stcsPage.dataset_proclib).toBeTruthy() + }) + + test('test values match with previous step', async ({ page }) => { + const ZoweValue = await stcsPage.get_zowe_value(); + const Zis_Value = await stcsPage.get_zis_value(); + const Aux_Value = await stcsPage.get_aux_value(); + await stcsPage.returnTitleOfPrevPage(); + const aux_value = await securityPage.get_aux_value(); + const stcZis_value = await securityPage.get_stc_zis_value(); + const stcZowe_value = await securityPage.get_stc_zowe_value(); + console.log(stcZowe_value,stcZis_value,aux_value) + + expect(ZoweValue).toBe(stcZowe_value); + expect(stcZis_value).toBe(Zis_Value); + expect(Aux_Value).toBe(aux_value); + }) + test('verify yaml updated on zos correctly', async ({ page }) => { + await stcsPage.initializeSTC() + const result = await script.runCommand(`cat ${process.env.ZOWE_ROOT_DIR}/zowe.yaml`); + await expect(result.details).toContain(config.SECURITY_AUX); + await expect(result.details).toContain(config.SECURITY_STC_ZOWE); + await expect(result.details).toContain(config.SECURITY_STC_ZIS); + }); + + + test('Test view yaml button', async ({ page }) => { + await stcsPage.viewYaml() + await expect(stcsPage.editor_title_element).toBeTruthy(); + await stcsPage.closeButton() + }) + + test('Test view job', async ({ page }) => { + await stcsPage.click_previewJob() + await expect(stcsPage.editor_title_element).toBeTruthy() + await stcsPage.closeButton() + }) + + test('test Previous step button is enabled', async ({ page }) => { + const is_prevButtonEnable = await stcsPage.isPreviousButtonEnable(); + expect(is_prevButtonEnable).toBe(true); + const title = await stcsPage.returnTitleOfPrevPage(); + expect(title).toBe(SECURITY_TITLE); + }) + + test('Test Skip Stcs button is enable', async ({ page }) => { + const isSkipStcsEnable = await stcsPage.is_skipStcsButtonEnable(); + expect(isSkipStcsEnable).toBe(true); + const certificate_title = await stcsPage.click_skipStcsButton(); + expect(certificate_title).toBe(CERTIFICATE_TITLE); + }) + + + test('Test continue to certificate button is disable', async ({ page }) => { + const is_ContinueButtonDisable = await stcsPage.isContinueButtonDisable(); + await expect(is_ContinueButtonDisable).toBe(true); + }) + + test('Test Resume Progress', async ({ page }) => { + await stcsPage.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 stcsPage.returnTitleOfStcsPage(); + expect(title).toBe(STCS_TITLE); + const ZoweValue = await stcsPage.get_zowe_value(); + const Zis_Value = await stcsPage.get_zis_value(); + const Aux_Value = await stcsPage.get_aux_value(); + const DatasetProclib_Value = await stcsPage.get_datasetProclib_value(); + expect(ZoweValue).toBe(config.SECURITY_STC_ZOWE); + expect(Aux_Value).toBe(config.SECURITY_AUX); + expect(Zis_Value).toBe(config.SECURITY_STC_ZIS); + expect(DatasetProclib_Value).toBe(config.PROC_LIB); + }) + + test('verify stcs applied successfully on zos after initialization', async ({ page }) => { + await stcsPage.initializeSTC() + const result = await script.runCommand(`tsocmd "LISTDS '${config.PROC_LIB}' MEMBERS"`); + await expect(result.details).toContain(config.SECURITY_AUX); + await expect(result.details).toContain(config.SECURITY_STC_ZOWE); + await expect(result.details).toContain(config.SECURITY_STC_ZIS); + + // verify all checks are sucessfully checked + const isWriteConfig_check_visible = await stcsPage.isWriteConfigGreenCheckVisible(); + expect(isWriteConfig_check_visible).toBe(true); + const isUploadConfig_check_visible = await stcsPage.isUploadConfigGreenCheckVisible(); + expect(isUploadConfig_check_visible).toBe(true); + const isInitStcs_check_visible = await stcsPage.isInitSTCSGreenCheckVisible(); + expect(isInitStcs_check_visible).toBe(true); + const is_GreenCheck_Visible = await stcsPage.isStatusChecked(); + expect(is_GreenCheck_Visible).toBe(false); + //verify continue Button enabled after init stcs// + const is_ContinueButtonDisable = await stcsPage.isContinueButtonDisable(); + expect(is_ContinueButtonDisable).toBe(false); + }); + +}) diff --git a/playwright_test/Tests/Vsam.spec.ts b/playwright_test/Tests/Vsam.spec.ts new file mode 100644 index 00000000..daa27271 --- /dev/null +++ b/playwright_test/Tests/Vsam.spec.ts @@ -0,0 +1,228 @@ +import { test, ElectronApplication, expect, _electron as electron } from '@playwright/test'; +import { prepareEnvironment } from '../prepare.js'; +import TitlePage from '../Pages/title.page.ts'; +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 NetworkingPage from '../Pages/networking.page.ts'; +import SecurityPage from '../Pages/security.page.ts' +import StcsPage from '../Pages/stcs.page.ts' +import config from '../utils/config'; +import ApfAuthPage from '../Pages/ApfAuth.page'; +import VsamPage from '../Pages/Vsam.page'; +import { connectArgs, Script } from '../setup'; + + +let electronApp: ElectronApplication +const VSAM_TITLE = 'CachingService' +const CERTIFICATE_TITLE = 'Certificates'; +const LAUNCHCONFIG_TITLE = 'Configuration' +const INVALID_ERRORMSG = 'must match pattern "^([A-Z$#@]){1}([A-Z0-9$#@-]){0,7}(.([A-Z$#@]){1}([A-Z0-9$#@-]){0,7}){0,11}$"' +const script = new Script() + +test.beforeAll(async () => { + test.setTimeout(600000); + try { + await prepareEnvironment({ install: true, cleanup:true, remove: false }); + } catch (error) { + console.error('Error during environment preparation:', error); + process.exit(1); + } +}); + +test.describe('VsamPage', () => { + let connectionPage: ConnectionPage; + let titlePage : TitlePage; + let installationTypePage : InstallationTypePage; + let planningPage : PlanningPage; + let installationPage : InstallationPage; + let networkingPage : NetworkingPage + let stcsPage : StcsPage + let securityPage : SecurityPage + let apfAuthPage : ApfAuthPage; + let vsamPage : VsamPage; + + test.beforeEach(async ({ page }) => { + test.setTimeout(900000); + electronApp = await electron.launch({ args: ['.webpack/main/index.js'] }) + 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); + securityPage = new SecurityPage(page); + stcsPage = new StcsPage(page); + vsamPage = new VsamPage(page); + titlePage.navigateToConnectionTab() + 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, + 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.clickOnContinueToUnpax() + 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 vsamPage.movetoVsamPage(); + }); + + test.afterEach(async () => { + await electronApp.close() + }) + + test('test title and required fields of page', async ({ page }) => { + const title = await vsamPage.returnTitleOfVsamPage(); + expect(title).toBe(VSAM_TITLE); + await expect(vsamPage.storage_mode).toBeTruthy() + await expect(vsamPage.Mode).toBeTruthy() + await expect(vsamPage.volume).toBeTruthy() + await expect(vsamPage.StorageClass).toBeTruthy() + await expect(vsamPage.VsamDatasetName).toBeTruthy() + }) + + test('test with invalid vsam dataset name ', async ({ page }) => { + await vsamPage.fillVsamDatasetName('%^%%&^') + const errorMsg = await vsamPage.invalidInput_ErrorMsg(); + expect(errorMsg).toBe(INVALID_ERRORMSG); + + }) + + + test('Test view yaml button', async ({ page }) => { + await vsamPage.viewYaml() + await expect(vsamPage.editor_title_element).toBeTruthy(); + await vsamPage.closeButton() + }) + + test('Test view job', async ({ page }) => { + await vsamPage.click_previewJob() + await expect(vsamPage.editor_title_element).toBeTruthy() + await vsamPage.closeButton() + }) + + test('click and verify Previous step button is enabled', async ({ page }) => { + const is_prevButtonEnable = await vsamPage.isPreviousButtonEnable(); + expect(is_prevButtonEnable).toBe(true); + const title = await vsamPage.returnTitleOfPrevPage(); + expect(title).toBe(CERTIFICATE_TITLE); + }) + + test('Click and verify Skip Vsam button is enabled', async ({ page }) => { + const isSkipStcsEnable = await vsamPage.is_skipVsamButtonEnable(); + expect(isSkipStcsEnable).toBe(true); + const reviewPage_title = await vsamPage.click_skipVsamButton(); + expect(reviewPage_title).toBe(LAUNCHCONFIG_TITLE); +}) + + + test('Test continue to lauch button is disable', async ({ page }) => { + const is_ContinueButtonDisable = await vsamPage.isContinueButtonDisable(); + expect(is_ContinueButtonDisable).toBe(true); + }) + + + test('Test fill vsam details RLS mode and verify all green checks', async ({ page }) => { + await vsamPage.select_storageMode('VSAM'); + await vsamPage.fillVsamDetails('RLS',config.VOLUME,config.STORAGECLASS, config.VSAM_DATASET_NAME) + await vsamPage.initializeVSAM(); + const isWriteConfig_check_visible = await vsamPage.isWriteConfigGreenCheckVisible(); + expect(isWriteConfig_check_visible).toBe(true); + const isUploadConfig_check_visible = await vsamPage.isUploadConfigGreenCheckVisible(); + expect(isUploadConfig_check_visible).toBe(true); + const isInitStcs_check_visible = await vsamPage.isInitVSAMGreenCheckVisible(); + expect(isInitStcs_check_visible).toBe(true); + const is_GreenCheck_Visible = await vsamPage.isStatusChecked(); + expect(is_GreenCheck_Visible).toBe(false); + + }) + + test('Test NONRLS YAML Update on z/OS After Init', async ({ page }) => { + await vsamPage.select_storageMode('VSAM'); + await vsamPage.fillVsamDetails('NONRLS',config.VOLUME,'', config.VSAM_DATASET_NAME) + await vsamPage.initializeVSAM(); + const result = await script.runCommand(`cat ${process.env.ZOWE_ROOT_DIR}/zowe.yaml`); + await expect(result.details).toContain('NONRLS'); + await expect(result.details).toContain(config.VOLUME); + await expect(result.details).toContain(config.VSAM_DATASET_NAME); + + const isWriteConfig_check_visible = await vsamPage.isWriteConfigGreenCheckVisible(); + expect(isWriteConfig_check_visible).toBe(true); + const isUploadConfig_check_visible = await vsamPage.isUploadConfigGreenCheckVisible(); + expect(isUploadConfig_check_visible).toBe(true); + const isInitStcs_check_visible = await vsamPage.isInitVSAMGreenCheckVisible(); + expect(isInitStcs_check_visible).toBe(true); + }); + + test('Verify VSAM dataset was successfully created on z/OS.', async ({ page }) => { + await vsamPage.select_storageMode('VSAM'); + await vsamPage.fillVsamDetails('RLS',config.VOLUME,'', config.VSAM_DATASET_NAME) + await vsamPage.initializeVSAM(); + const result = await script.runCommand(`tso "LISTCAT"`); + + await expect(result.details).toContain(config.VSAM_DATASET_NAME); + + }); + + + test('Test save and close and Resume Progress', async ({ page }) => { + await vsamPage.select_storageMode('VSAM'); + await vsamPage.fillVsamDetails('NONRLS',config.VOLUME,'', config.VSAM_DATASET_NAME) + await vsamPage.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 vsamPage.returnTitleOfVsamPage(); + expect(title).toBe(VSAM_TITLE); + const vsamMode = await vsamPage.get_VsamMode_value(); + const vsamVolume = await vsamPage.get_VsamVolume_value(); + const storageClass = await vsamPage.get_StorageClass_value(); + const vsamDatasetName = await vsamPage.get_VsamDatasetName_value(); + expect(vsamMode).toBe('NONRLS'); + expect(vsamVolume).toBe(config.VOLUME); + expect(storageClass).toBe(''); + expect(vsamDatasetName).toBe(config.VSAM_DATASET_NAME); + }) + + + test('Test skip vsam page if Infinispan storage Mode', async ({ page }) => { + await vsamPage.select_storageMode('INFINISPAN'); + const is_ContinueButtonDisable = await vsamPage.isContinueButtonEnabled(); + expect(is_ContinueButtonDisable).toBe(true); + const is_InitVsam_Button_Visible = await vsamPage.is_initVsamButtonVisible(); + expect(is_InitVsam_Button_Visible).toBe(false) + const isVolumeVisible = await vsamPage.isElement_Visible(vsamPage.volume); + await expect(isVolumeVisible).toBeFalsy(); + const isModeVisible = await vsamPage.isElement_Visible(vsamPage.mode); + await expect(isModeVisible).toBeFalsy(); + const isStorageClassVisible = await vsamPage.isElement_Visible(vsamPage.StorageClass); + await expect(isStorageClassVisible).toBeFalsy(); + const isVsamdatasetnameVisible = await vsamPage.isElement_Visible(vsamPage.VsamDatasetName); + await expect(isVsamdatasetnameVisible).toBeFalsy(); + await expect(vsamPage.storage_mode).toBeTruthy() + + + }) +}) diff --git a/playwright_test/Tests/titleTab.spec.ts b/playwright_test/Tests/titleTab.spec.ts index 1a4ef432..c1d35490 100644 --- a/playwright_test/Tests/titleTab.spec.ts +++ b/playwright_test/Tests/titleTab.spec.ts @@ -15,8 +15,8 @@ test.describe('Home', () => { test('Open HomePage and verify title', async ({ page }) => { // verify title - // page = await electronApp.firstWindow() - await expect(page).toHaveTitle('Zowe Enterprise Necessity'); + page = await electronApp.firstWindow() + await expect(page).toHaveTitle('Zowe Server Install Wizard'); }) test('Verify install buttons', async ({ page }) => { @@ -25,4 +25,4 @@ test.describe('Home', () => { await expect(titlePage.zoweInstallButton).toBeVisible() await expect(titlePage.zoweDryrunButton).toBeVisible() }) -}) \ No newline at end of file +}) diff --git a/playwright_test/prepare.js b/playwright_test/prepare.js index 01a7f6b7..e6567bab 100644 --- a/playwright_test/prepare.js +++ b/playwright_test/prepare.js @@ -1,7 +1,7 @@ -const Script = require('./setup.js'); +import { connectArgs, Script } from './setup'; -async function prepareEnvironment(options = {}) { - const { install = false, remove = false } = options; +export async function prepareEnvironment(options = {}) { + const { install = false, cleanup= false, remove = false } = options; const SSH_HOST = process.env.SSH_HOST; const SSH_PORT = process.env.SSH_PORT; @@ -14,6 +14,12 @@ async function prepareEnvironment(options = {}) { const JAVA_HOME = process.env.JAVA_HOME; const NODE_HOME = process.env.NODE_HOME; const DATASET_PREFIX = process.env.DATASET_PREFIX; + const LOAD_LIB = process.env.LOAD_LIB; + const PARM_LIB = process.env.PARM_LIB; + const JCL_LIB = process.env.JCL_LIB; + const VSAM_DATASET_NAME = process.env.VSAM_DATASET_NAME; + const VOLUME = process.env.VOLUME; + const STORAGECLASS = process.env.STORAGECLASS; const AUTH_LOAD_LIB = process.env.AUTH_LOAD_LIB; const AUTH_PLUGIN_LIB = process.env.AUTH_PLUGIN_LIB; const SECURITY_ADMIN = process.env.SECURITY_ADMIN; @@ -63,9 +69,27 @@ async function prepareEnvironment(options = {}) { } if (!DATASET_PREFIX) { throw new Error('DATASET_PREFIX is not defined'); - } + } if (!AUTH_LOAD_LIB) { throw new Error('AUTH_LOAD_LIB is not defined'); + } + if (!LOAD_LIB) { + throw new Error('LOAD_LIB is not defined'); + } + if (!PARM_LIB) { + throw new Error('PARM_LIB is not defined'); + } + if (!JCL_LIB) { + throw new Error('JCL_LIB is not defined'); + } + if (!VSAM_DATASET_NAME) { + throw new Error('VSAM_DATASET_NAME is not defined'); + } + if (!VOLUME) { + throw new Error('VOLUME is not defined'); + } + if (!STORAGECLASS) { + throw new Error('STORAGECLASS is not defined'); } if (!AUTH_PLUGIN_LIB) { throw new Error('AUTH_PLUGIN_LIB is not defined'); @@ -103,7 +127,7 @@ async function prepareEnvironment(options = {}) { if (!EXTERNAL_PORT) { throw new Error('EXTERNAL_PORT is not defined'); } - + const scriptRunner = new Script({ host: SSH_HOST, port: SSH_PORT, @@ -112,15 +136,21 @@ async function prepareEnvironment(options = {}) { }); if (install) { + console.time('Installation Time'); await scriptRunner.install(ZOWE_ROOT_DIR); + console.timeEnd('Installation Time'); console.log('Installation complete.'); } - - if (remove) { + if (cleanup) { + await scriptRunner.remove_createdDataset(DATASET_PREFIX,LOAD_LIB,AUTH_PLUGIN_LIB,AUTH_LOAD_LIB,PARM_LIB, JCL_LIB, VSAM_DATASET_NAME); + console.log("Removed all created datasets") + } + + if (remove) { await scriptRunner.remove(ZOWE_ROOT_DIR); console.log('Removal complete.'); } - + console.log('Preparation complete.'); } diff --git a/playwright_test/setup.js b/playwright_test/setup.js deleted file mode 100644 index 97bc6361..00000000 --- a/playwright_test/setup.js +++ /dev/null @@ -1,108 +0,0 @@ -const zos = require('zos-node-accessor'); -const https = require('https'); - -class Script { - constructor(config) { - this.config = config; - } - - async mkdir(installDir) { - const script = `mkdir -p ${installDir}`; - return this.run(script); - } - - async remove(installDir) { - const script = `rm -rf ${installDir}`; - return this.run(script); - } - - static getZoweVersion() { - return new Promise((resolve, reject) => { - https.get('https://raw.githubusercontent.com/zowe/zowe-install-packaging/v2.x/master/manifest.json.template', (res) => { - let data = ''; - - res.on('data', (chunk) => { - data += chunk; - }); - - res.on('end', () => { - try { - const parsedData = JSON.parse(data); - resolve({ status: true, details: parsedData.version }); - } catch (error) { - reject({ status: false, details: { error } }); - } - }); - - }).on('error', (error) => { - reject({ status: false, details: { error } }); - }); - }); - } - - async download(installDir) { - try { - const { status, details: version } = await Script.getZoweVersion(); - if (!status) { - throw new Error('Failed to retrieve Zowe version.'); - } - const script = `URL="https://zowe.jfrog.io/zowe/list/libs-release-local/org/zowe"; -curl $URL/${version}/zowe-${version}.pax --k --o ${installDir}/zowe.pax` - return this.run(script); - } catch (error) { - console.error('Error:', error); - return null; - } - } - - async unpax(installDir) { - const script = `cd ${installDir};\npax -ppx -rf zowe.pax;\nrm zowe.pax`; - return this.run(script); - } - - async install(installDir) { - try { - await this.mkdir(installDir); - await this.download(installDir); - await this.unpax(installDir); - console.log('Installation completed successfully.'); - } catch (error) { - console.error('Installation failed:', error); - } - } - - async run(script) { - const jcl = `//ZWEJOB01 JOB IZUACCT,'SYSPROG',CLASS=A, -// MSGLEVEL=(1,1),MSGCLASS=A -//RUNSCRP EXEC PGM=BPXBATCH,REGION=0M -//STDOUT DD SYSOUT=* -//STDERR DD SYSOUT=* -//STDPARM DD * -sh set -x; -${script}; -echo "Script finished." -/* `; - - try { - console.log('Connecting to FTP server...'); - const client = new zos(); - await client.connect(this.config); - - if (!client.connected) { - throw new Error('Failed to connect to ' + this.config.host); - } - const result = await client.submitJCL(jcl, ["STDOUT", "STDERR"]); - console.log('JCL submitted successfully.'); - console.log('Result:', result); - return result; - } catch (error) { - console.error('Error:', error); - return null; - } - } -} - -module.exports = Script; - diff --git a/playwright_test/setup.ts b/playwright_test/setup.ts new file mode 100644 index 00000000..d1c37d8b --- /dev/null +++ b/playwright_test/setup.ts @@ -0,0 +1,159 @@ +import { submitJcl } from '../src/services/SubmitJcl'; +import { startBPXBATCHAndShellSession } from '../src/services/ServiceUtils'; +import { JCL_UNIX_SCRIPT_OK } from '../src/renderer/components/common/Utils'; +import config from './utils/config'; +import * as https from 'https'; + + +// Define the response type based on what submitJcl returns +interface Response { + rc: number; + jobOutput?: { [key: string]: string }; +} + +// Define the type for the result that this function returns +interface CommandResult { + status: boolean; + details: string; +} + +// Initialize the config object directly from the imported config +const connectArgs = { + jobStatement: `//ZWEJOB01 JOB IZUACCT,'SYSPROG',CLASS=A,\n// MSGLEVEL=(1,1),MSGCLASS=A`, + host: config.SSH_HOST, + port: config.SSH_PORT, + user: config.SSH_USER, + password: config.SSH_PASSWD +}; + +class Script { + + async runCommand(command: string, timeout: number = 60000): Promise { + const jcl = `${connectArgs.jobStatement} +${startBPXBATCHAndShellSession("ZNCKNOD")} +${command} && +echo "${JCL_UNIX_SCRIPT_OK}" +/* `; + + const timeoutPromise = new Promise((_, reject) => { + setTimeout(() => { + reject(new Error('Command execution timed out.')); + }, timeout); + }); + + const commandPromise = submitJcl({ + jobStatement: connectArgs.jobStatement, + host: connectArgs.host, + port: connectArgs.port || 21, + user: connectArgs.user, + password: connectArgs.password + }, jcl, ["STDOUT", "STDERR"]); + + try { + const resp = await Promise.race([commandPromise, timeoutPromise]); + + // Streamlined job output processing + const output = resp.jobOutput?.["3"] ?? "No output found"; + return { + status: resp.rc === 0, + details: resp.rc === 0 ? output : `${resp.rc}: ${resp.jobOutput}` + }; + } catch (error) { + console.error('Error during command execution:', error); + throw error; + } +} + + async unpax(installDir: string): Promise { + const script = `cd ${installDir};\npax -ppx -rf zowe.pax;\nrm zowe.pax`; + + try { + const result = await this.runCommand(script); + if (!result.status) { + throw new Error(`unpax command failed. Details: ${result.details}`); + } + return result; + } catch (error) { + console.error(`Error during unpax operation: ${error.message}`); + throw new Error(`unpax operation failed: ${error.message}`); + } + } + + async download(installDir) { + try { + const { status, details: version } = await Script.getZoweVersion(); + if (!status) { + throw new Error('Failed to retrieve Zowe version.'); + } + const script = `URL="https://zowe.jfrog.io/zowe/list/libs-release-local/org/zowe"; + curl -L $URL/${version}/zowe-${version}.pax + -k + -o ${installDir}/zowe.pax` + return this.runCommand(script); + } catch (error) { + console.error('Error:', error); + return null; + } + } + + static getZoweVersion() { + return new Promise((resolve, reject) => { + https.get('https://raw.githubusercontent.com/zowe/zowe-install-packaging/v3.x/master/manifest.json.template', (res) => { + let data = ''; + + res.on('data', (chunk) => { + data += chunk; + }); + + res.on('end', () => { + try { + const parsedData = JSON.parse(data); + resolve({ status: true, details: parsedData.version }); + } catch (error) { + reject({ status: false, details: { error } }); + } + }); + + }).on('error', (error) => { + reject({ status: false, details: { error } }); + }); + }); + } + async mkdir(installDir) { + const script = `mkdir -p ${installDir}`; + return this.runCommand(script); + } + + async remove(installDir) { + const script = `rm -rf ${installDir}`; + return this.runCommand(script); + } + + async remove_createdDataset(dataset_prefix, loadlib, authPluginLib, authLoadlib, parmlib, jcllib, vsam) { + const script = ` + tsocmd "DELETE '${dataset_prefix}.SZWEEXEC'"; + tsocmd "DELETE '${dataset_prefix}.SZWESAMP'"; + tsocmd "DELETE '${loadlib}'"; + tsocmd "DELETE '${authPluginLib}'"; + tsocmd "DELETE '${authLoadlib}'"; + tsocmd "DELETE '${parmlib}'"; + tsocmd "DELETE '${jcllib}'"; + tsocmd "DELETE '${vsam}'" + `; + + return this.runCommand(script); +} + + async install(installDir) { + try { + await this.mkdir(installDir); + await this.download(installDir); + await this.unpax(installDir); + console.log('Installation completed successfully.'); + } catch (error) { + console.error('Installation failed:', error); + } + } + } + +export { connectArgs, Script }; diff --git a/playwright_test/utils/config.ts b/playwright_test/utils/config.ts index 2acdca11..95e14579 100644 --- a/playwright_test/utils/config.ts +++ b/playwright_test/utils/config.ts @@ -31,7 +31,10 @@ interface Config { SECURITY_AUX: string | undefined; SECURITY_STC_ZOWE: string | undefined; SECURITY_STC_ZIS: string | undefined; - + VOLUME: string | undefined; + STORAGECLASS: string | undefined; + VSAM_DATASET_NAME: string | undefined; + } const config: Config = { @@ -50,7 +53,7 @@ const config: Config = { 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, + 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, @@ -66,7 +69,11 @@ const config: Config = { 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 + DOMAIN_NAME: process.env.DOMAIN_NAME, + VOLUME:process.env.VOLUME, + STORAGECLASS:process.env.STORAGECLASS, + VSAM_DATASET_NAME:process.env.VSAM_DATASET_NAME + }; export default config;