From cb42c39646d117936cf6f1cb4396970263b2b957 Mon Sep 17 00:00:00 2001 From: Xaranti <85513286+Xaranti@users.noreply.github.com> Date: Thu, 4 Nov 2021 13:41:08 +0100 Subject: [PATCH 01/20] dadas dadas --- regresja/from selenium import webdriver.py | 57 ++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 regresja/from selenium import webdriver.py diff --git a/regresja/from selenium import webdriver.py b/regresja/from selenium import webdriver.py new file mode 100644 index 0000000..a26d415 --- /dev/null +++ b/regresja/from selenium import webdriver.py @@ -0,0 +1,57 @@ +from selenium import webdriver +from selenium.webdriver.common.keys import Keys +import time + +###############TEST 1 - Logowanie #################### +try: + PATH = "D:\chromedriver.exe" + driver = webdriver.Chrome(PATH) # or ...Chrome(executable_path=sciezka) + driver.get("http://localhost:28558/") + driver.maximize_window() + time.sleep(2) + log = driver.find_element_by_name('login') + log.send_keys('m.stasiak@xopero.com') + + pas = driver.find_element_by_id('mat-input-1') + pas.send_keys('Admin_123') + + driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-content/main/div/app-auth/div/app-auth-login/div/form/app-save-button/button').click() + time.sleep(1) + title = driver.current_url + if title == 'http://localhost:28558/devices': + print ("Test 1 - Logowanie: Pass") + else: + print("Test 1 - Logowanie: Failed") +except: + print("Test 1 - Logowanie: Failed") + +#################Test 2 - Dodawanie urządzenia############# +try: + if driver.find_element_by_id("mat-badge-content-0").is_displayed(): + driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-toolbar-container/app-toolbar/mat-toolbar/mat-toolbar-row/div[2]/button[1]').click() + time.sleep(1) + driver.find_element_by_xpath('//*[@id="mat-checkbox-2"]/label/span[1]').click() + driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-activate-devices-table/div/div[4]/app-save-button/button/span[1]').click() + time.sleep(1) + driver.find_element_by_xpath('//app-license[2]/p').click() + driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-licenses-list/div/div[4]/app-save-button/button/span[1]/span').click() + print('Test 2 - Dodawanie urządzenia: Pass') + else: + print('Test 2 - Dodawanie urządzenia: Pass(Brak urządzeń do dodania)') +except: + print('Test 2 - Dodawanie urządzenia: Failed') + + +##############Test 3 - Dodawanie magazynu lokalnego########## + +driver.find_element_by_xpath('/html/body/app-root/app-main/app-menu/section/nav[1]/a[6]').click() +driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-toolbar-container/app-toolbar/mat-toolbar/mat-toolbar-row/div[1]/ng-component/button/span[1]').click() +driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/mat-form-field').find_element_by_xpath('//*[@id="mat-input-3"]').click() +# pwd_ele = driver.find_element_by_xpath('//*[@id="mat-input-3"]') +# print(pwd_ele.is_displayed()) #return true/false based on element status +# print(pwd_ele.is_enabled()) +# pwd_ele.click() + + +time.sleep(2) +#driver.close() \ No newline at end of file From 5e5055550d2541d7453ea026ef22d49e012d2593 Mon Sep 17 00:00:00 2001 From: Xaranti <85513286+Xaranti@users.noreply.github.com> Date: Wed, 24 Nov 2021 13:49:15 +0100 Subject: [PATCH 02/20] Add files via upload --- Testy Regresji.py | 317 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100644 Testy Regresji.py diff --git a/Testy Regresji.py b/Testy Regresji.py new file mode 100644 index 0000000..deadf96 --- /dev/null +++ b/Testy Regresji.py @@ -0,0 +1,317 @@ +from selenium import webdriver +from selenium.webdriver.common.keys import Keys +import time + +PATH = "D:\chromedriver.exe" +driver = webdriver.Chrome(PATH) # or ...Chrome(executable_path=sciezka) + +###############TEST 1 - Logowanie #################### +def logowanie(): + try: + driver.get("http://localhost:28555/") + driver.maximize_window() + time.sleep(2) + log = driver.find_element_by_name('login') + log.send_keys('admin@xopero.com') + + pas = driver.find_element_by_id('mat-input-1') + pas.send_keys('Admin_123') + + driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-content/main/div/app-auth/div/app-auth-login/div/form/app-save-button/button').click() + time.sleep(1) + title = driver.current_url + if title == 'http://localhost:28555/devices': + print ("Test 1 - Logowanie: Pass") + return + else: + print("Test 1 - Logowanie: Failed") + return + except: + print("Test 1 - Logowanie: Failed") + exit() + + +#################Test 2 - Dodawanie urządzenia############# +def dodanieUrzadzenia(): + try: + if driver.find_element_by_id("mat-badge-content-0").is_displayed(): + driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-toolbar-container/app-toolbar/mat-toolbar/mat-toolbar-row/div[2]/button[1]').click() + time.sleep(1) + driver.find_element_by_xpath('//*[@id="mat-checkbox-2"]/label/span[1]').click() + driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-activate-devices-table/div/div[4]/app-save-button/button/span[1]').click() + time.sleep(1) + driver.find_element_by_xpath('//app-license[2]/p').click() + driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-licenses-list/div/div[4]/app-save-button/button/span[1]/span').click() + print('Test 2 - Dodawanie urządzenia: Pass') + return + else: + print('Test 2 - Dodawanie urządzenia: Pass(Brak urządzeń do dodania)') + return + except: + print('Test 2 - Dodawanie urządzenia: Failed') + return + +################Test Kontrola Xopero Storage#################### +def xoperoStorage(): + driver.implicitly_wait(5) + time.sleep(2) + driver.find_element_by_xpath("//*[contains(text(),'Magazyny')]").click() #wybór magazynu + time.sleep(1) + print('Test Kontrola Xopero Storage: ', driver.find_element_by_xpath("//*[contains(text(),'Xopero Storage #1')]").is_displayed()) + return + +#############Test 3 - Dodawanie magazynu lokalnego########## +def dodajLokalny(): + try: + driver.find_element_by_xpath('/html/body/app-root/app-main/app-menu/section/nav[1]/a[6]').click() + driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-toolbar-container/app-toolbar/mat-toolbar/mat-toolbar-row/div[1]/ng-component/button/span[1]').click() + driver.find_element_by_xpath("/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/mat-form-field").click() + elem = driver.find_element_by_xpath("/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/mat-form-field/div/div[1]/div[2]/input")# + ID = (elem.get_attribute("id")) + driver.find_element_by_xpath('//*[@id="%s"]' %(ID)).clear() + driver.find_element_by_xpath('//*[@id="%s"]' %(ID)).send_keys("magazyn lokalny") + matInput=int(ID[-2:]) + if matInput>=0: + pass + else: + matInput=int(ID[-1:]) + matInput+=2 + driver.find_element_by_xpath('//*[@id="mat-input-%d"]' %(matInput)).send_keys("D:\storage testowy") + driver.find_element_by_xpath("//*[contains(text(),'Zapisz')]").click() + print ("Test 3 - Dodawanie magazynu lokalnego: Pass") + except: + print ("Test 3 - Dodawanie magazynu lokalnego: Failed") + try: + driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/div[1]/app-close-aside-button/button').click() + driver.find_element_by_xpath('//*[@id="mat-dialog-8"]/app-modal/div/div[3]/button[2]').click() + except: + pass + return + +time.sleep(2) +##############Test 4 - Dodawanie magazynu SMB########## +def dodajSMB(): + try: + driver.find_element_by_xpath('/html/body/app-root/app-main/app-menu/section/nav[1]/a[6]').click() + driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-toolbar-container/app-toolbar/mat-toolbar/mat-toolbar-row/div[1]/ng-component/button/span[1]').click() + driver.find_element_by_xpath("/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/mat-form-field").click() + elem = driver.find_element_by_xpath("/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/mat-form-field/div/div[1]/div[2]/input")# + ID = (elem.get_attribute("id")) + driver.find_element_by_xpath('//*[@id="%s"]' %(ID)).clear() + driver.find_element_by_xpath('//*[@id="%s"]' %(ID)).send_keys("magazyn SMB") + time.sleep(1) + matInput=int(ID[-2:]) + if matInput>=0: + pass + else: + matInput=int(ID[-1:]) + matInput+=4 + driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/div[2]/form/ng-select/div').click() + driver.find_element_by_xpath("//*[contains(text(),'Lokalizacja sieciowa')]").click() + driver.find_element_by_xpath('//*[@id="mat-input-%d"]' %(matInput)).send_keys("admin") + driver.find_element_by_xpath("//*[contains(text(),'Wybierz lub dodaj')]").click() + driver.find_element_by_xpath("/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-passwords-list-container/app-passwords-list/div/div[3]/button").click() + matInput+=1 + driver.find_element_by_xpath('//*[@id="mat-input-%d"]' %(matInput)).send_keys("admin") + matInput+=1 + driver.find_element_by_xpath('//*[@id="mat-input-%d"]' %(matInput)).send_keys("Admin_123") + matInput+=1 + driver.find_element_by_xpath('//*[@id="mat-input-%d"]' %(matInput)).send_keys("Admin_123") + driver.find_element_by_xpath("/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-passwords-form-container/app-passwords-form/form/div[3]/app-save-button/button/span[1]").click() + matInput-=4 + driver.find_element_by_xpath('//*[@id="mat-input-%d"]' %(matInput)).send_keys("\\\\192.168.0.198\Public\MStasiak") + driver.find_element_by_xpath("//*[contains(text(),'Zapisz')]").click() + print ("Test 3 - Dodawanie magazynu SMB: Pass") + except: + print ("Test 3 - Dodawanie magazynu SMB: Failed") + try: + driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/div[1]/app-close-aside-button/button').click() + driver.find_element_by_xpath('//*[@id="mat-dialog-8"]/app-modal/div/div[3]/button[2]').click() + except: + pass + time.sleep(2) + return + +#############Test 4 - Dodawanie magazynu NFS######### +def dodajNFS(): + try: + driver.find_element_by_xpath('/html/body/app-root/app-main/app-menu/section/nav[1]/a[6]').click() + driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-toolbar-container/app-toolbar/mat-toolbar/mat-toolbar-row/div[1]/ng-component/button/span[1]').click() + driver.find_element_by_xpath("/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/mat-form-field").click() + elem = driver.find_element_by_xpath("/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/mat-form-field/div/div[1]/div[2]/input")# + ID = (elem.get_attribute("id")) + driver.find_element_by_xpath('//*[@id="%s"]' %(ID)).clear() + driver.find_element_by_xpath('//*[@id="%s"]' %(ID)).send_keys("magazyn NFS") + matInput=int(ID[-2:]) + if matInput>=0: + pass + else: + matInput=int(ID[-1:]) + driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/div[2]/form/ng-select/div').click() + driver.find_element_by_xpath("//*[contains(text(),'Network File Storage')]").click() + matInput+=3 + driver.find_element_by_xpath('//*[@id="mat-input-%d"]' %(matInput)).send_keys("192.168.0.198:/StorageNFS") + driver.find_element_by_xpath("//*[contains(text(),'Zapisz')]").click() + print ("Test 4 - Dodawanie magazynu NFS: Pass") + except: + print ("Test 4 - Dodawanie magazynu NFS: Failed") + try: + driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/div[1]/app-close-aside-button/button').click() + driver.find_element_by_xpath('//*[@id="mat-dialog-8"]/app-modal/div/div[3]/button[2]').click() + except: + pass + time.sleep(1) + return + +def kontrolaZadania(): + time.sleep(2) + x = True + while x: + if driver.find_element_by_xpath('/html/body/app-root/app-main/app-menu/section/nav[1]/a[7]/span[1]/app-icon/span').is_displayed(): + time.sleep(5) + else: + x = False + driver.fin('/html/body/app-root/app-main/div/app-content/div[2]/aside/app-aside/ng-component/app-dashboard-plan/div/div[1]/app-close-aside-button/button').click() + print("Zakończono zadanie") + return + +#############Test 5 - Logowanie organizacji GitHub####### +def zalogujGH(): + try: + driver.get("https://github.com/") + time.sleep(2) + driver.find_element_by_xpath("//*[contains(text(),'Sign in')]").click() + time.sleep(2) + GH = driver.find_element_by_name("login") + GH.send_keys("stasiak.marek93@gmail.com") + PASY = driver.find_element_by_name("password") + PASY.send_keys("Plokijuh1.") + driver.find_element_by_name("commit").click() + print ("Test 5 - Logowanie organizacji GitHub: Pass") + except: + print ("Test 5 - Logowanie organizacji GitHub: Failed") + time.sleep(1) + driver.get("http://localhost:28555/git") + return + +#############Test 6 - Dodawanie organizacji GitHub####### +def dodajGH(): + try: + driver.implicitly_wait(10) + driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-content/main/div/ng-component/app-organizations/ng-containter/app-git-no-organizations/div/button[2]').click() #wybór git do utworzenia + driver.find_element_by_xpath("//*[contains(text(),'Kontynuuj')]").click() + time.sleep(5) + driver.find_element_by_xpath("/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-git-organization/div/div[5]/app-save-button/button").click() #zatwierdzenie tworzenia git + print("Test 6 - Dodawanie organizacji GitHub: Pass") + except: + print('Test 6 - Dodawanie organizacji GitHub: Failed') + time.sleep(1) + return +#############Test 7 - Dodawanie i uruchomienie planu predefiniowanego do organizacji GitHub####### +def predefiniowany(): + try: + driver.find_element_by_xpath('//*[@id="mat-dialog-0"]/app-modal/div/div[3]/button[2]/span[1]').click() + print ("Test 7 - Dodawanie i uruchomienie planu predefiniowanego do organizacji GitHub: Pass") + except: + try: + driver.get("http://localhost:28555/git") + driver.find_element_by_xpath("/html/body/app-root/app-main/div/app-content/main/div/ng-component/app-organizations/ng-containter/app-organization-container/app-organization/section/article/app-simplified-backup-plans/div/div/div/button/span[1]").click() + time.sleep(3) + driver.find_element_by_xpath("//*[contains(text(),'Git Protection')]").click() + print("Test 7 - Dodawanie planu predefiniowanego do organizacji GitHub: Pass") + except: + print("Test 7 - Dodawanie planu predefiniowanego do organizacji GitHub: Failed") + time.sleep(1) + #############Test 8 - Uruchamianie planu predefiniowanego do organizacji GitHub####### + try: + time.sleep(1) + driver.find_element_by_xpath("//*[contains(text(),'Wykonaj teraz')]").click() + print("Test 8 - Uruchamianie planu predefiniowanego do organizacji GitHub: Pass") + except: + print ("Test 8 - Uruchamianie planu predefiniowanego do organizacji GitHub: Failed") + time.sleep(2) + kontrolaZadania() + + +##################Test 10 - Podsumowanie backupu GIT (test 8)################# +def podsumowanie(): + driver.find_element_by_xpath("//*[contains(text(),'Zadania')]").click() #wybór zadań + driver.find_element_by_xpath("//*[contains(text(),'Ostatnie 24 godziny')]").click() #wybór wykonanych zadań + okelem = driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-content/main/div/ng-component/article/mat-tab-group/div/mat-tab-body[2]/div/app-packages/mat-accordion/app-package[1]/mat-expansion-panel/mat-expansion-panel-header/span/div[2]/app-package-tasks-statuses/div[1]/div/span[1]') + OK = (okelem.get_attribute("innerHTML")) + time.sleep(1) + warelem = driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-content/main/div/ng-component/article/mat-tab-group/div/mat-tab-body[2]/div/app-packages/mat-accordion/app-package[1]/mat-expansion-panel/mat-expansion-panel-header/span/div[2]/app-package-tasks-statuses/div[2]/div/span[1]') + Warnings = (warelem.get_attribute("innerHTML")) + time.sleep(1) + nokelem = driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-content/main/div/ng-component/article/mat-tab-group/div/mat-tab-body[2]/div/app-packages/mat-accordion/app-package[1]/mat-expansion-panel/mat-expansion-panel-header/span/div[2]/app-package-tasks-statuses/div[3]/div/span') + NOK = (nokelem.get_attribute("innerHTML")) + time.sleep(1) + print("Pomyślnie zakończono %s repozytoriów" %(OK)) + print("Ostrzeżeniami zakończono %s repozytoriów " %(warelem)) + print("Błędami zakończono %s repozytoriów" %(NOK)) + return + +#################Test 11 - Kontrola przywróconych backupów (test8)######################## +def kontrolaBackupu(): + driver.find_element_by_xpath('/html/body/app-root/app-main/app-menu/section/nav[1]/a[4]').click() + #time.sleep(30) + plany = 0 + time.sleep(2) + driver.find_element_by_xpath("/html/body/app-root/app-main/div/app-content/main/div/ng-component/app-organizations/ng-containter/app-organization-container/app-organization/section/footer/button[2]").click() + time.sleep(2) + for i in range(1,11): + driver.find_element_by_xpath("/html/body/app-root/app-main/div/app-content/main/div/ng-component/app-repositories/article/app-table/cdk-virtual-scroll-viewport/div[1]/table/tbody/tr[%d]/td[7]/button[2]/span[1]" %(i)).click() + time.sleep(5) + try: + driver.find_element_by_xpath("//*[contains(text(),'Wyświetl dostępne plany, a następnie wybierz backup do przywrócenia')]").is_displayed() + print("Brak planu backup") + except: + print("Plan backup dostępny") + plany+=1 + print("Utworzono ", plany, "na 10 planów") + return + +#################Test 12 - przywracanie backupu (test8)################# +def przywracanieGH(): + driver.implicitly_wait(5) + driver.find_element_by_xpath('/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-resource-backups/div/div[3]/div/app-browser-container/app-browser/div/div/app-browser-backups/div/div/div[2]/div/button').click() + time.sleep(3) + driver.find_element_by_xpath("//*[contains(text(),'Restore all')]").click() + time.sleep(3) + driver.find_element_by_xpath("//*[contains(text(),'Start now')]").click() + driver.find_element_by_xpath("//*[contains(text(),'Zadania')]").click() #wybór zadań + time.sleep(2) + kontrolaZadania() + driver.find_element_by_xpath("//*[contains(text(),'Last 24 hours')]").click() #wybór wykonanych zadań + print("Wykonano przywracanie repozytorium GH") + return + +for i in range(1,100): + if i==1: + logowanie() + elif i==2: + dodanieUrzadzenia() + elif i==3: + xoperoStorage() + elif i==4: + dodajLokalny() + elif i==5: + dodajSMB() + elif i==6: + dodajNFS() + elif i==7: + zalogujGH() + elif i==8: + dodajGH() + elif i==9: + predefiniowany() + elif i==10: + podsumowanie() + elif i==11: + kontrolaBackupu() + elif i==12: + przywracanieGH() + else: + exit() + +#driver.close() \ No newline at end of file From 1a1a46b2a512b4a0ae4c3deef1fdb46b1a374d63 Mon Sep 17 00:00:00 2001 From: Xaranti <85513286+Xaranti@users.noreply.github.com> Date: Wed, 29 Dec 2021 11:43:31 +0100 Subject: [PATCH 03/20] Create python-package-conda.yml x --- .github/workflows/python-package-conda.yml | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/python-package-conda.yml diff --git a/.github/workflows/python-package-conda.yml b/.github/workflows/python-package-conda.yml new file mode 100644 index 0000000..9bd6d2b --- /dev/null +++ b/.github/workflows/python-package-conda.yml @@ -0,0 +1,34 @@ +name: Python Package using Conda + +on: [push] + +jobs: + build-linux: + runs-on: ubuntu-latest + strategy: + max-parallel: 5 + + steps: + - uses: actions/checkout@v2 + - name: Set up Python 3.10 + uses: actions/setup-python@v2 + with: + python-version: 3.10 + - name: Add conda to system path + run: | + # $CONDA is an environment variable pointing to the root of the miniconda directory + echo $CONDA/bin >> $GITHUB_PATH + - name: Install dependencies + run: | + conda env update --file environment.yml --name base + - name: Lint with flake8 + run: | + conda install flake8 + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Test with pytest + run: | + conda install pytest + pytest From 183d56b2a8359a40663557240b27761e8759e513 Mon Sep 17 00:00:00 2001 From: Xaranti <85513286+Xaranti@users.noreply.github.com> Date: Wed, 29 Dec 2021 11:49:46 +0100 Subject: [PATCH 04/20] Create python-publish.yml --- .github/workflows/python-publish.yml | 36 ++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/python-publish.yml diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml new file mode 100644 index 0000000..3bfabfc --- /dev/null +++ b/.github/workflows/python-publish.yml @@ -0,0 +1,36 @@ +# This workflow will upload a Python Package using Twine when a release is created +# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +name: Upload Python Package + +on: + release: + types: [published] + +jobs: + deploy: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install build + - name: Build package + run: python -m build + - name: Publish package + uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 + with: + user: __token__ + password: ${{ secrets.PYPI_API_TOKEN }} From c8bbda7ea24efdddc0182cf2d324d2ee4c9357e5 Mon Sep 17 00:00:00 2001 From: Marek_Stasiak Date: Thu, 24 Feb 2022 12:18:02 +0100 Subject: [PATCH 05/20] LFS --- .gitattributes | 1 + File50MB.7z.iso | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 .gitattributes create mode 100644 File50MB.7z.iso diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..5a93236 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.iso filter=lfs diff=lfs merge=lfs -text diff --git a/File50MB.7z.iso b/File50MB.7z.iso new file mode 100644 index 0000000..fa5af5a --- /dev/null +++ b/File50MB.7z.iso @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:23c7b46f89fa7c3c6d44f12d17cd284a0f7f45ec185855b14187896ea9f0c42e +size 52428800 From ab57d1ec78b73032fdc5a3abd13c301dec884a56 Mon Sep 17 00:00:00 2001 From: Xaranti <85513286+Xaranti@users.noreply.github.com> Date: Sun, 1 May 2022 22:22:43 +0200 Subject: [PATCH 06/20] Create locators Python locators with examples --- locators | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 locators diff --git a/locators b/locators new file mode 100644 index 0000000..7b132dd --- /dev/null +++ b/locators @@ -0,0 +1,27 @@ +from selenium import webdriver +import time +from selenium.webdriver.common.keys import Keys +from soupsieve import select +from selenium.webdriver.support.select import Select +from selenium.webdriver.common.by import By + +PATH = 'C:\Program Files (x86)\chromedriver.exe' +driver = webdriver.Chrome(PATH) +#driver.get("https://www.animezone.pl/anime/filmy") +driver.get("https://login.salesforce.com/") +driver.get("https://rahulshettyacademy.com/angularpractice/") +time.sleep(2) +#driver.find_element_by_xpath("//i[@class='fa fa-home']").click() #xpath samemu napisany +#driver.find_element_by_css_selector("i[class='fa fa-home']").click() #css selector +#print (driver.find_element_by_css_selector("i[class='fa fa-home']").text) # wyświetli text jaki posiada element +#driver.find_element_by_css_selector(".form-control").send_keys('xd') # szukanie po classname poprzedamy kropka, a po id hasem +#print(driver.find_element_by_css_selector(".alert-danger").text) +#driver.find_element_by_xpath("//a[text()='Zapomniałem hasła']").click() +#driver.find_element_by_xpath("//div[@id='usernamegroup']/label").send_keys("x") +#driver.find_element_by_css_selector("div[id='usernamegroup'] label").send_keys("x")) + +#print(driver.find_element_by_xpath("//form[@name='login']/div[1]/label").text) + +dropdown = Select(driver.find_element(By.ID,"exampleFormControlSelect1")) +dropdown.select_by_visible_text("Female") +dropdown.select_by_index(0) From 7b16b0b416c6696eb17e8622ed1dfa3a112552e5 Mon Sep 17 00:00:00 2001 From: Xaranti <85513286+Xaranti@users.noreply.github.com> Date: Mon, 9 May 2022 13:28:02 +0200 Subject: [PATCH 07/20] Update locators pomo w wyszukiwaniu css i xpath --- locators | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/locators b/locators index 7b132dd..ee1b767 100644 --- a/locators +++ b/locators @@ -25,3 +25,7 @@ time.sleep(2) dropdown = Select(driver.find_element(By.ID,"exampleFormControlSelect1")) dropdown.select_by_visible_text("Female") dropdown.select_by_index(0) + +pomoc w wyszukiwaniu elementów w konsoli: +document.querySelectorAll('.nazwa-klasy') - daje mi wszystkie elementy które to spełniają +document.querySelector('.nazwa-klasy') - daje mi 1 element na stronie jaki znajdzie From 73b25c9bb6a9a62e12a8e1b853cbf649e1a494f1 Mon Sep 17 00:00:00 2001 From: Xaranti <85513286+Xaranti@users.noreply.github.com> Date: Thu, 12 May 2022 15:23:57 +0200 Subject: [PATCH 08/20] sciezka backupu --- sciezka restora.py | 146 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 sciezka restora.py diff --git a/sciezka restora.py b/sciezka restora.py new file mode 100644 index 0000000..14a0002 --- /dev/null +++ b/sciezka restora.py @@ -0,0 +1,146 @@ +from selenium import webdriver +from selenium.webdriver.common.keys import Keys +from selenium.webdriver.common.by import By +from selenium.webdriver.support.relative_locator import locate_with +from selenium.webdriver.common.action_chains import ActionChains +import time + +PATH = "D:\chromedriver.exe" +driver = webdriver.Chrome(PATH) # or ...Chrome(executable_path=sciezka) + +###############TEST 1 - Logowanie #################### +def logowanie(): + try: + driver.get("http://localhost:28555") # <-- url usługi + driver.maximize_window() + time.sleep(2) + + + log = driver.find_element(By.NAME,'login') + log.send_keys('admin@xopero.com') # <-- login + time.sleep(1) + + pas = driver.find_element(By.ID,'mat-input-1') + pas.send_keys("Admin_123") #<-- hasło + + driver.find_element(By.XPATH,"//button[@type='submit']").click() + time.sleep(1) + title = driver.current_url + + if title == 'http://localhost:28555/devices': + print ("Test 1 - Logowanie: Pass") + return + + else: + print("Test 1 - Logowanie: Failed") + return + + except: + print("Test 1 - Logowanie: Failed") + exit() + + +def kontrolaZadania(): + try: + time.sleep(1) + print(" Zadanie w trakcie wykonywania") + x = True + + while x: + if driver.find_element(By.XPATH,'//*[@id="mat-badge-content-7"]').is_displayed(): + time.sleep(5) + else: + x = False + + try: + driver.find_element(By.XPATH,'/html/body/app-root/app-main/div/app-content/div[2]/aside/app-aside/ng-component/app-dashboard-plan/div/div[1]/app-close-aside-button/button').click() + except: + pass + + print(" Zakończono zadanie") + return + except: + return + + +def podsumowanie(): + try: + driver.find_element(By.XPATH,"//*[contains(text(),'Tasks')]").click() #wybór zadań + driver.find_element(By.XPATH,"//*[contains(text(),'Last 24 hours')]").click() #wybór wykonanych zadań + + ########################################## + OK = driver.find_element(By.XPATH,"//span[text()='OK']") + Success = driver.find_element(locate_with(By.CLASS_NAME, "count").above(OK)).text + + warning = driver.find_element(By.XPATH,"//span[text()='warnings']") + warnResult = driver.find_element(locate_with(By.CLASS_NAME, "count").above(warning)).text + + NOK = driver.find_element(By.XPATH,"//span[text()='errors']") + errors = driver.find_element(locate_with(By.CLASS_NAME, "count").above(NOK)).text + + print(" Podsumowanie wykonania zadania: Pass") + print(" Pomyślnie zakończono %s zadań" %(Success)) + print(" Ostrzeżeniami zakończono %s zadań " %(warnResult)) + print(" Błędami zakończono %s zadań" %(errors)) + + except: + print("Podsumowanie wykonania zadania: Failed") + return + +def fileBackupCLD(): + driver.implicitly_wait(5) + driver.find_element(By.XPATH,"//*[contains(text(),'Plans')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'Add plan')]").click() + + driver.find_element(By.NAME,"backupPlanName").clear() + driver.find_element(By.NAME,"backupPlanName").send_keys("File backup on Cloud") + + driver.find_element(By.XPATH,"//*[contains(text(),'How to protect')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'File-level')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'Which devices?')]").click() + + mainDevice = driver.find_element(By.XPATH,"//span[text()='Main']/../../..") + mainDevice.find_element(By.CLASS_NAME, "mat-checkbox").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'Apply')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'What to protect?')]").click() + + driver.find_element(By.XPATH,'/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-add-rule/div/div[3]/div[2]/div[2]/div/h3').click() + + + folderTree = driver.find_element(By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside[3]/app-aside/ng-component/app-add-device-rule/div/div[2]/app-files-browser/app-files/ul") + y = R"D:\pliki\jsony jira" ##<--- wstaw ścieżkę backupu + y=y.replace(":","") + backupPath = y.split("\\") + fileName = backupPath.pop(-1) + + for folder in backupPath: + folderName = folderTree.find_element(By.XPATH,"//span[text()='%s']/../.." %(folder)) + folderName.find_element(By.CSS_SELECTOR,"svg[data-icon='plus']").click() + + fileNameElem = folderTree.find_element(By.XPATH,"//*[contains(text(),'%s')]" %(fileName)) + driver.find_element(locate_with(By.CLASS_NAME, "mat-checkbox-layout").to_left_of(fileNameElem)).click() + + driver.find_element(By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside[3]/app-aside/ng-component/app-add-device-rule/div/div[3]/button/span[1]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'Apply')]").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'Where to store?')]").click() + time.sleep(1) + driver.find_element(By.XPATH,"//*[contains(text(),'Xopero Storage')]").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'When?')]").click() + startAt = driver.find_element(By.XPATH,'/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-add-schedule/form/div[3]/div/mat-accordion/mat-expansion-panel[1]/div/div/app-monthly/div/mat-radio-group/div/div[2]/app-time/mat-form-field/div/div[1]/div/input') + startAt.send_keys('1111') + driver.find_element(By.XPATH,"//*[contains(text(),'Next')]").click() + driver.find_element(By.XPATH,"//button[@type='submit']").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'Save&Run')]").click() + + # kontrolaZadania() + # podsumowanie() + + return() + +logowanie() +fileBackupCLD() + From 3fc543dfb53296cb0720792d6a7908d0c765ad79 Mon Sep 17 00:00:00 2001 From: Xaranti <85513286+Xaranti@users.noreply.github.com> Date: Mon, 16 May 2022 09:34:41 +0200 Subject: [PATCH 09/20] Update python-package-conda.yml --- .github/workflows/python-package-conda.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/python-package-conda.yml b/.github/workflows/python-package-conda.yml index 9bd6d2b..9539a0f 100644 --- a/.github/workflows/python-package-conda.yml +++ b/.github/workflows/python-package-conda.yml @@ -7,6 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: max-parallel: 5 + ziemniak: pyrka steps: - uses: actions/checkout@v2 From 89eb05cac07279eee7a3c1bd298f71494ddd0261 Mon Sep 17 00:00:00 2001 From: Xaranti <85513286+Xaranti@users.noreply.github.com> Date: Thu, 19 May 2022 08:46:13 +0200 Subject: [PATCH 10/20] selenium mocno --- FileBackUp/Main.py | 28 ++++++++ .../__pycache__/fileBackupPath.cpython-39.pyc | Bin 0 -> 2660 bytes .../__pycache__/fileRestore.cpython-39.pyc | Bin 0 -> 3164 bytes .../__pycache__/pathBackup.cpython-39.pyc | Bin 0 -> 2046 bytes .../__pycache__/sideTasks.cpython-39.pyc | Bin 0 -> 980 bytes .../__pycache__/supportTask.cpython-39.pyc | Bin 0 -> 1438 bytes .../__pycache__/systemVariable.cpython-39.pyc | Bin 0 -> 2215 bytes .../__pycache__/xoperoVariable.cpython-39.pyc | Bin 0 -> 2260 bytes FileBackUp/fileBackupPath.py | 60 ++++++++++++++++ FileBackUp/fileRestore.py | 67 ++++++++++++++++++ FileBackUp/pathBackup.py | 48 +++++++++++++ FileBackUp/sideTasks.py | 36 ++++++++++ FileBackUp/supportTask.py | 57 +++++++++++++++ FileBackUp/systemVariable.py | 48 +++++++++++++ FileBackUp/xoperoVariable.py | 49 +++++++++++++ 15 files changed, 393 insertions(+) create mode 100644 FileBackUp/Main.py create mode 100644 FileBackUp/__pycache__/fileBackupPath.cpython-39.pyc create mode 100644 FileBackUp/__pycache__/fileRestore.cpython-39.pyc create mode 100644 FileBackUp/__pycache__/pathBackup.cpython-39.pyc create mode 100644 FileBackUp/__pycache__/sideTasks.cpython-39.pyc create mode 100644 FileBackUp/__pycache__/supportTask.cpython-39.pyc create mode 100644 FileBackUp/__pycache__/systemVariable.cpython-39.pyc create mode 100644 FileBackUp/__pycache__/xoperoVariable.cpython-39.pyc create mode 100644 FileBackUp/fileBackupPath.py create mode 100644 FileBackUp/fileRestore.py create mode 100644 FileBackUp/pathBackup.py create mode 100644 FileBackUp/sideTasks.py create mode 100644 FileBackUp/supportTask.py create mode 100644 FileBackUp/systemVariable.py create mode 100644 FileBackUp/xoperoVariable.py diff --git a/FileBackUp/Main.py b/FileBackUp/Main.py new file mode 100644 index 0000000..71ca2a3 --- /dev/null +++ b/FileBackUp/Main.py @@ -0,0 +1,28 @@ +#region Imports +import sideTasks +import fileBackupPath +import fileRestore +import pathBackup +import systemVariable +import xoperoVariable +import time +from selenium import webdriver +#endregion + +PATH = "D:\chromedriver.exe" +driver = webdriver.Chrome(PATH) # or ...Chrome(executable_path=sciezka) + +sideTasks.logowanie(driver) + +fileBackupPath.fileBackupCLD(driver,"fileBackup") +pathBackup.pathBackup(driver,"By Path","E:\\abecadlo") + +xoperoVariables = ["HOMES","USERS_DOCUMENTS","USERS_DESKTOP","USERS_DOWNLOADS"] +for variable in xoperoVariables: + planName = 'Zmienna %s' %(variable) + xoperoVariable.xoperoVar(driver,planName,variable) + time.sleep(1) + +systemVariable.systemVar(driver,"System Var","smieci") + +fileRestore.FileRestore_Cloud(driver,"Xopero Storage #1 (XoperoOneEmea)","fileBackup") diff --git a/FileBackUp/__pycache__/fileBackupPath.cpython-39.pyc b/FileBackUp/__pycache__/fileBackupPath.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..553387e36a47d10536b7067ce1b3f174aefa89c7 GIT binary patch literal 2660 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 literal 0 HcmV?d00001 diff --git a/FileBackUp/__pycache__/sideTasks.cpython-39.pyc b/FileBackUp/__pycache__/sideTasks.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3bd3f2661fda954abbbc97a59bf79d36369dc735 GIT binary patch literal 980 zcmZuw&2AGh5VpNP-Td@N98gsulv{~V6IxWMiU73*Dv+S6)S`k33Y)b_-Rz%ir)gH{ zseJ$*Avy9EyZ|q-S5AEePK?t~a;PnjXFh+P@z`U3e!hsHef@RS&Mky~8)LQ+Ft%Z+ zEf5Sb9HIzQjEzo05?R!m=vHV)4s|BF9lF$I4s)*%on!VPs?J@*ZdAp2q0ie)iZd?3 zAiD#Qr7#J6&0Bq;Pxb?Bh|^}n?80~nL;VDijfQ9hXBb0#(C`>xq{+x)WQy3@Idz#e zCKq^!M-bcK6NWRx@R$n>G9C^>n7{)BvHDtv9-Cmd2KG5I$_cg zakk{MNW|OcNy=qX3zF#CTuWApe7z>(w5QkBX<^53TI(B6v*mid-P1aWKX2Q zUON(c^-K2f?qGGs&qTmgwtU2uuB=zqD({j`()VM*8Q6c9kEq?>B#X}zPSW74^MD6{Z_pfO|aaic`fuiK?E9!ha z*g1MbogfrJmzIK_l(3=IlVR?pQp7s9`MJgaC-3&)pIN)DZ}V(X64%;;o8%wgK~cRlO{A_# s9{L(SMQidE5-CmPOV0=sZ<5}OSOhHho<#}kh5Usn4Q04xY`RDO0($=dg#Z8m literal 0 HcmV?d00001 diff --git a/FileBackUp/__pycache__/supportTask.cpython-39.pyc b/FileBackUp/__pycache__/supportTask.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5039223df8ec3b613feb43e7d39c71f209707274 GIT binary patch literal 1438 zcmZvcUvJws5Wq?5kLA?qIKxycBJRXln^5>(gt1AfF>whi=cdH2f zYX&zPfx$L>$_R!S4pD@=7#p30B(l0zpQ-2VdC+^zK0to; z3Zft%=hX=xFd3Y22?O$M3i4JchE((ZB+w^&Lu?$E&E(+1_Z&WT0U}E@y2K1GAP-F# zIXC%Ob3DUxdxkD8ZJ#>KUXV+7f#g=<>loiRYs{VFH)~nr+N%Oyl?B4+6^d&ZdW?QY zF?np_dM55GIO#!QH#0_mTu8sVcV&{y)|;kvDWh?~o0F!NbUZZLbS&cO1g!KhyWi=2 zb+jF@r|S{btpQ~t-WrNn^H{gOTkl;t5NS7i*E!Kq*ck{m?a(A?Ng;HhL^OyyEI2C$ z%XMaawAt%W6);{*lv+H3$WbCMC2J)iEyI|l-@sDXV;Bm>TgB4WAk|vL zow7^UAgATo#^UdbVJ2eH%*u26UT*6k;<=+j&Xe3pWDx7T_D2x2J`Z^Wn@bA<G5t5@@I57 zewiGrG)aWihg6N*$u$22E?7$u((>|Y1=g!32!sh70L)Fm?{0~o_E^P$S7OLK^S9Z{?iqm0%L57Oq2_P( zL;vdya}#RA?`01@I{ktw-Q4`Pc_LD2+lU1 zr&4@s0@soo3El&XYJe~p)N$SN0EIgK9M|u-_%@dJVaBiKo&rweAdRG{FZmZAhVARp z)Q102B;xj9TB7{uBQ8rM+meS=Lp|#kRZPg@z|s&|z*cN}BWr`YEK>KLM1rLu|K1c6 NWv;G<&Cj#E#(!CcdvpK* literal 0 HcmV?d00001 diff --git a/FileBackUp/__pycache__/systemVariable.cpython-39.pyc b/FileBackUp/__pycache__/systemVariable.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ec38f7f3dcf218dd4d49c6a2a9639a34a7353144 GIT binary patch literal 2215 zcmZ`)%~KmU6yFbjVGL<0r8JO^r!$Rl8+((shfb%o5K1SVNhlN3l3*A{yAt-s+SQIE z1NP8c{t!6!U)pO=oO^0deNT=ZjLq6B={^14_tT2Z%@r+pI{&=&U&HEeByK(q5F7BS z?_i)7wYe492eyrChdYsb;F`6|Gg0;+Yt|W_JIK*2&Aqh_@-)-1s`+b>wyJhIbH;os z!&4@KaGv&HoaG`QnjN2oy1f&)2z>YCV8(X~UX=k)F04!N;0mnwmtbvc=Z#C9E9WwE zW!cug6_;$7ZR@oaJC6}PK)6H1J5H8nfRjU+F;1RlFYF}?^^at8w`5(KpWqZGI5Sty zpYDZg>=$TpVt;mmQ<~t+fsV{Y#^{)#^P~L%$EEj1oI#v3^n+U*mwtGQGeZ}ElfQ7r zVx08mqoJHGUe40RG4#j7y-|*qCODsf@7as&Wu7jN$$mP4yg$KNnc%DrIn;t)da!ey zg@))q@VqaZfrvE;W3{H)xn8S2s_b$St4j5#U!JX|qzYf(<5&@9lX{qw1~Uqa4moSia`nCZIq+hNcyQ+65#O#Oto&pb~hByJ8u zSg*W*fGS5`y*~K&OA*nvpv{7gFV61>doxLR50$M=b!@*)^o)GPksFVZ*kP#Lg+(5zgiZaMQZUFDd z0Fw;kQd&rc3Anbgi>4Rpl}MNr~A=ONwqX#0~w?VZ@9|G+H|e8K)!2 zJFTW7Y32z${ne>i-+@z!*<1EJzpJ%~n;W{9VAZ;Q6ly5z^kdo}r|jX&E*{f6GQUSu z2b-!|O7DeH!owicymx#?LYK6v)uBl`W}ZciUd){;!UA&2-8c?yT`_vCO~ zXFchGv%_}Bi&1UBVA)06v6t)|{1%)Adl_E%IrD~EaA6*->_syd%{UKI1HN1Z9o0fw zKriF48%ezL)72qaA6?mXXiey#y5Acl^{Xim)lCv1bzL$}G~DyY=5`lSWP>b5!itKIMM%v*{JSg>j0DfM~XV66*GP;3Dwq%E65HD%@%wB000pA%Y9=-kSs3*3LVZIv37) z=EAbAEh{eDFx%GeR_r`ObRXdk5Lc2c&446_IwO)i&7RqF7TO=`=5FY^G(RROj7f?Y z&L8fXYy1~zX>5IJOi~_`OoNTgS;p8X(wX6UU*gg`LrFi+BK_!w#HDv{NQ!j!hQy^G zpE;28RSk!Ek4JcKfYGJ%Df-DsmF5O(L;X+3B=e9@_AGmzr=N}J-XB9Qj7b*9Bo77> zYC(TJT))ghlk^^V-WNN8h&2ggwWQgpUaCE5b2Chf}>7? z8tWutJ?D|?J)WrbQk+z@s3cNo7HG8o`9$1LA!l{Yju}VHWLsP9FlbjOI}QV;en8wq z&r=DBcls$TS6@Ry)jhA#=>L1=i0FFIX2Fp!PH#!OnIyc6#+D`qw$S_a1LGtZ;p z@z86FamcL_Y8EMkVsR>+q|#Agd}zYy-9x+-oGn)a5%~hbsov(X#dPJ63!m_c>~Lnb zWFbDRE8}Lz4`a%S&-ijRhT4M}s6zYeVKi?=!lbAi6B!bp@)U4W@vr!_4>&ctPib03ryW&AUToNkFrHC`Bh3;0E#N zFk;3eI;|gsjME|H%4!%V9i3*L!_`}ySoL){tXREy&+|K4i+JaS?k2F2s^dqYhTWQc zdRyd}J$}={(|b$hH;FpJUaOVUJ7JXYFbFm8?w^oQr{x1^x_#)s2&yRY<&$RLZZtPv zrr7|1M`>og`Faf*Mr2x44A4ictJ2cyt7faUZ&u5zK(*Fht*vhU@+Qq-Inu1+j3u>P zn(M#r(gHqW@R^d%jJ9T4!j1pY9R75we-?hm6PM)`UzWTNk^T3Se!IKT)w_}% zN~YeCU3|8zz?u9t*&VgnNV;ipD8hHBT7ki`OSWUr**W;lI7Si602*;(%=o-|r1*PUxYA-|d(6$pnb%B#Dr^AsHtc qJ_`2Dr+|<$14iX64(QKhe{EPmmxb>lft~(6o=sJNp={%?;QSA<@0Y&- literal 0 HcmV?d00001 diff --git a/FileBackUp/fileBackupPath.py b/FileBackUp/fileBackupPath.py new file mode 100644 index 0000000..89156d7 --- /dev/null +++ b/FileBackUp/fileBackupPath.py @@ -0,0 +1,60 @@ +import supportTask + +from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.support.relative_locator import locate_with +import time + +def fileBackupCLD(driver,planName): + driver.implicitly_wait(5) + driver.find_element(By.XPATH,"//*[contains(text(),'Plans')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'Add plan')]").click() + + driver.find_element(By.NAME,"backupPlanName").clear() + driver.find_element(By.NAME,"backupPlanName").send_keys("%s" %(planName)) + + driver.find_element(By.XPATH,"//*[contains(text(),'How to protect')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'File-level')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'Which devices?')]").click() + + mainDevice = driver.find_element(By.XPATH,"//span[text()='Main']/../../..") + mainDevice.find_element(By.CLASS_NAME, "mat-checkbox").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'Apply')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'What to protect?')]").click() + + driver.find_element(By.XPATH,'/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-add-rule/div/div[3]/div[2]/div[2]/div/h3').click() + + + folderTree = driver.find_element(By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside[3]/app-aside/ng-component/app-add-device-rule/div/div[2]/app-files-browser/app-files/ul") + y = R"D:\pliki\jsony jira" ##<--- wstaw ścieżkę backupu + y=y.replace(":","") + backupPath = y.split("\\") + fileName = backupPath.pop(-1) + + for folder in backupPath: + folderName = folderTree.find_element(By.XPATH,"//span[text()='%s']/../.." %(folder)) + folderName.find_element(By.CSS_SELECTOR,"svg[data-icon='plus']").click() + + fileNameElem = folderTree.find_element(By.XPATH,"//*[contains(text(),'%s')]" %(fileName)) + driver.find_element(locate_with(By.CLASS_NAME, "mat-checkbox-layout").to_left_of(fileNameElem)).click() + + driver.find_element(By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside[3]/app-aside/ng-component/app-add-device-rule/div/div[3]/button/span[1]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'Apply')]").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'Where to store?')]").click() + time.sleep(1) + driver.find_element(By.XPATH,"//*[contains(text(),'Xopero Storage')]").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'When?')]").click() + startAt = driver.find_element(By.XPATH,'/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-add-schedule/form/div[3]/div/mat-accordion/mat-expansion-panel[1]/div/div/app-monthly/div/mat-radio-group/div/div[2]/app-time/mat-form-field/div/div[1]/div/input') + startAt.send_keys('1111') + driver.find_element(By.XPATH,"//*[contains(text(),'Next')]").click() + driver.find_element(By.XPATH,"//button[@type='submit']").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'Save&Run')]").click() + + return + + + diff --git a/FileBackUp/fileRestore.py b/FileBackUp/fileRestore.py new file mode 100644 index 0000000..f208077 --- /dev/null +++ b/FileBackUp/fileRestore.py @@ -0,0 +1,67 @@ +from selenium import webdriver +from selenium.webdriver.common.keys import Keys +from selenium.webdriver.common.by import By +from selenium.webdriver.support.relative_locator import locate_with +from selenium.webdriver.common.action_chains import ActionChains +import time + +def FileRestore_Cloud(driver,storage,backupName): + driver.implicitly_wait(5) + + driver.find_element(By.XPATH,'/html/body/app-root/app-main/app-menu/section/nav[1]/a[6]/span[2]').click() + + time.sleep(3) + location = driver.find_element(By.XPATH,"//*[contains(text(),'%s')]" %(storage)) ##<--- wstaw nazwę magazynu, z którego chcesz przywracać + parentLocation1 = location.find_element(By.XPATH,'./../..') + parentLocation1.find_element(By.CLASS_NAME, "mat-button-wrapper").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'Select resource')]").click() + driver.find_element(By.XPATH,'/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-select-worker/div/div[2]/app-filters-table/button').click() + x = driver.find_element(By.XPATH,'/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-select-worker/div/div[2]/app-filters-table/form/div/app-filters/app-filter-input/input') + x.send_keys('STASIAK-M') + + time.sleep(2) + driver.find_element(By.XPATH,"//*[contains(text(),'Apply')]").click() + time.sleep(2) + driver.find_element(By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-select-worker/div/div[3]/div/div/div/div").click() + time.sleep(1) + + try: + driver.find_element(By.XPATH,"//*[contains(text(),'View available plans')]").is_displayed() + driver.find_element(By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-resource-backups/div/div[3]/ng-select").click() + driver.find_element(By.XPATH,"//*[contains(text(),'%s')]" %(backupName)).click() + except: + pass + + driver.implicitly_wait(5) + driver.find_element(By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-resource-backups/div/div[3]/div[2]/app-browser-container/app-browser/div/div/app-browser-backups/div/div/div[2]/div/button/span[1]").click() + time.sleep(1) + driver.find_element(By.XPATH,"//*[contains(text(),'Restore all')]").click() + time.sleep(1) + + driver.find_element(By.XPATH,"//*[contains(text(),'Select directory')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'New directory')]").click() + + driver.find_element(By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside[4]/app-aside/ng-component/app-browse-device-files/div/div[3]/app-files-browser/app-files/ul/li[2]/div/app-icon").click() + + folderTree = driver.find_element(By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside[4]") + restorePath = R"backup\Cloud" ##<--- wstaw ścieżkę backupu + restorePath=restorePath.replace(":","") + backupPath = restorePath.split("\\") + fileName = backupPath.pop(-1) + + for folder in backupPath: + time.sleep(1) + folderTree.find_element(By.XPATH,"//span[text()='%s']/../../app-icon/fa-icon" %(folder)).click() + #folderName.find_element(By.XPATH,"//*/app-icon").click() + + fileNameElem = folderTree.find_element(By.XPATH,"//span[text()='%s']" %(fileName)) + time.sleep(1) + driver.find_element(locate_with(By.CSS_SELECTOR, "label[class='mat-checkbox-layout']").to_left_of(fileNameElem)).click() + + + driver.find_element(By.XPATH,"//*[contains(text(),'Apply')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'Start now')]").click() + print("Test 1 - Uruchomienie FB restore z CLD: Pass") + + return() \ No newline at end of file diff --git a/FileBackUp/pathBackup.py b/FileBackUp/pathBackup.py new file mode 100644 index 0000000..03bcc84 --- /dev/null +++ b/FileBackUp/pathBackup.py @@ -0,0 +1,48 @@ +from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.support.relative_locator import locate_with +import time + +def pathBackup(driver,planName,backupPath): + driver.implicitly_wait(5) + try: + driver.find_element(By.XPATH,"//*[contains(text(),'Plans')]").click() + except: + pass + driver.find_element(By.XPATH,"//*[contains(text(),'Add plan')]").click() + + driver.find_element(By.NAME,"backupPlanName").clear() + driver.find_element(By.NAME,"backupPlanName").send_keys("%s" %(planName)) + + driver.find_element(By.XPATH,"//*[contains(text(),'How to protect')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'File-level')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'Which devices?')]").click() + + mainDevice = driver.find_element(By.XPATH,"//span[text()='Main']/../../..") + mainDevice.find_element(By.CLASS_NAME, "mat-checkbox").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'Apply')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'What to protect?')]").click() + + + selectItems = driver.find_element(By.XPATH,"//div[text()='Select items to back up using']/..") + selectItems.find_element(By.CSS_SELECTOR,"div[role='combobox']").click() + selectItems.find_element(By.XPATH,"//*[contains(text(),'Set global rules')]").click() + driver.find_element(By.CSS_SELECTOR,"input[formcontrolname='path']").send_keys(backupPath) + #driver.find_element(By.CSS_SELECTOR,"svg[data-icon='check']").click() + driver.find_element(By.XPATH,"//*[contains(text(),'Apply')]").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'Where to store?')]").click() + time.sleep(1) + driver.find_element(By.XPATH,"//*[contains(text(),'Xopero Storage')]").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'When?')]").click() + startAt = driver.find_element(By.XPATH,'/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-add-schedule/form/div[3]/div/mat-accordion/mat-expansion-panel[1]/div/div/app-monthly/div/mat-radio-group/div/div[2]/app-time/mat-form-field/div/div[1]/div/input') + startAt.send_keys('1111') + driver.find_element(By.XPATH,"//*[contains(text(),'Next')]").click() + driver.find_element(By.XPATH,"//button[@type='submit']").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'Save&Run')]").click() + + + diff --git a/FileBackUp/sideTasks.py b/FileBackUp/sideTasks.py new file mode 100644 index 0000000..b849219 --- /dev/null +++ b/FileBackUp/sideTasks.py @@ -0,0 +1,36 @@ +from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.support.relative_locator import locate_with +import time + +def logowanie(driver): + try: + driver.get("http://localhost:28555") # <-- url usługi + driver.maximize_window() + time.sleep(2) + + + log = driver.find_element(By.NAME,'login') + log.send_keys('admin@xopero.com') # <-- login + time.sleep(1) + + pas = driver.find_element(By.ID,'mat-input-1') + pas.send_keys("Admin_123") #<-- hasło + + driver.find_element(By.XPATH,"//button[@type='submit']").click() + time.sleep(1) + title = driver.current_url + + if title == 'http://localhost:28555/devices': + print ("Test 1 - Logowanie: Pass") + return + + else: + print("Test 1 - Logowanie: Failed") + return + + except: + print("Test 1 - Logowanie: Failed") + exit() + + diff --git a/FileBackUp/supportTask.py b/FileBackUp/supportTask.py new file mode 100644 index 0000000..73e9dab --- /dev/null +++ b/FileBackUp/supportTask.py @@ -0,0 +1,57 @@ +from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.support.relative_locator import locate_with +import time + + +def kontrolaZadania(driver): + try: + time.sleep(1) + print(" Zadanie w trakcie wykonywania") + x = True + + while x: + if driver.find_element(By.XPATH,'//*[@id="mat-badge-content-7"]').is_displayed(): + time.sleep(5) + else: + x = False + + try: + driver.find_element(By.XPATH,'/html/body/app-root/app-main/div/app-content/div[2]/aside/app-aside/ng-component/app-dashboard-plan/div/div[1]/app-close-aside-button/button').click() + except: + pass + + print(" Zakończono zadanie") + return + except: + return + +def podsumowanie(driver): + try: + driver.find_element(By.XPATH,"//*[contains(text(),'Tasks')]").click() #wybór zadań + driver.find_element(By.XPATH,"//*[contains(text(),'Last 24 hours')]").click() #wybór wykonanych zadań + + ########################################## + statuses = ["OK","warnings","errors"] + for status in statuses: + attribute = driver.find_element(By.XPATH,"//span[text()='%s']" %(status)) + result = driver.find_element(locate_with(By.CLASS_NAME, "count").above(attribute)).text + print(status,":",result) + + # OK = driver.find_element(By.XPATH,"//span[text()='OK']") + # Success = driver.find_element(locate_with(By.CLASS_NAME, "count").above(OK)).text + + # warning = driver.find_element(By.XPATH,"//span[text()='warnings']") + # warnResult = driver.find_element(locate_with(By.CLASS_NAME, "count").above(warning)).text + + # NOK = driver.find_element(By.XPATH,"//span[text()='errors']") + # errors = driver.find_element(locate_with(By.CLASS_NAME, "count").above(NOK)).text + + # print(" Podsumowanie wykonania zadania: Pass") + # print(" Pomyślnie zakończono %s zadań" %(Success)) + # print(" Ostrzeżeniami zakończono %s zadań " %(warnResult)) + # print(" Błędami zakończono %s zadań" %(errors)) + + except: + print("Podsumowanie wykonania zadania: Failed") + return() \ No newline at end of file diff --git a/FileBackUp/systemVariable.py b/FileBackUp/systemVariable.py new file mode 100644 index 0000000..4eb40ef --- /dev/null +++ b/FileBackUp/systemVariable.py @@ -0,0 +1,48 @@ +from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.support.relative_locator import locate_with +import time + +def systemVar(driver,planName,systemVariable): + driver.implicitly_wait(5) + try: + driver.find_element(By.XPATH,"//*[contains(text(),'Plans')]").click() + except: + pass + driver.find_element(By.XPATH,"//*[contains(text(),'Add plan')]").click() + + driver.find_element(By.NAME,"backupPlanName").clear() + driver.find_element(By.NAME,"backupPlanName").send_keys("%s" %(planName)) + + driver.find_element(By.XPATH,"//*[contains(text(),'How to protect')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'File-level')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'Which devices?')]").click() + + mainDevice = driver.find_element(By.XPATH,"//span[text()='Main']/../../..") + mainDevice.find_element(By.CLASS_NAME, "mat-checkbox").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'Apply')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'What to protect?')]").click() + + + selectItems = driver.find_element(By.XPATH,"//div[text()='Select items to back up using']/..") + selectItems.find_element(By.CSS_SELECTOR,"div[role='combobox']").click() + selectItems.find_element(By.XPATH,"//*[contains(text(),'Set global rules')]").click() + + driver.find_element(By.CSS_SELECTOR, "ng-select[bindlabel='name']").click() + driver.find_element(By.XPATH,"//h4[text()='System variable']").click() + driver.find_element(By.CSS_SELECTOR,"input[formcontrolname='systemVariable']").send_keys(systemVariable) + driver.find_element(By.XPATH,"//*[contains(text(),'Apply')]").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'Where to store?')]").click() + time.sleep(1) + driver.find_element(By.XPATH,"//*[contains(text(),'Xopero Storage')]").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'When?')]").click() + startAt = driver.find_element(By.XPATH,'/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-add-schedule/form/div[3]/div/mat-accordion/mat-expansion-panel[1]/div/div/app-monthly/div/mat-radio-group/div/div[2]/app-time/mat-form-field/div/div[1]/div/input') + startAt.send_keys('1111') + driver.find_element(By.XPATH,"//*[contains(text(),'Next')]").click() + driver.find_element(By.XPATH,"//button[@type='submit']").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'Save&Run')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'Tasks')]").click() diff --git a/FileBackUp/xoperoVariable.py b/FileBackUp/xoperoVariable.py new file mode 100644 index 0000000..822b70b --- /dev/null +++ b/FileBackUp/xoperoVariable.py @@ -0,0 +1,49 @@ +from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.support.relative_locator import locate_with +import time + +def xoperoVar(driver,planName,xoperoVariable): + driver.implicitly_wait(5) + try: + driver.find_element(By.XPATH,"//*[contains(text(),'Plans')]").click() + except: + pass + driver.find_element(By.XPATH,"//*[contains(text(),'Add plan')]").click() + + driver.find_element(By.NAME,"backupPlanName").clear() + driver.find_element(By.NAME,"backupPlanName").send_keys("%s" %(planName)) + + driver.find_element(By.XPATH,"//*[contains(text(),'How to protect')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'File-level')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'Which devices?')]").click() + + mainDevice = driver.find_element(By.XPATH,"//span[text()='Main']/../../..") + mainDevice.find_element(By.CLASS_NAME, "mat-checkbox").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'Apply')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'What to protect?')]").click() + + + selectItems = driver.find_element(By.XPATH,"//div[text()='Select items to back up using']/..") + selectItems.find_element(By.CSS_SELECTOR,"div[role='combobox']").click() + selectItems.find_element(By.XPATH,"//*[contains(text(),'Set global rules')]").click() + + driver.find_element(By.CSS_SELECTOR, "ng-select[bindlabel='name']").click() + driver.find_element(By.XPATH,"//h4[text()='Xopero variable']").click() + driver.find_element(By.CSS_SELECTOR, "ng-select[formcontrolname='xoperoVariable']").click() + driver.find_element(By.XPATH,"//h4[text()='%s']" %(xoperoVariable)).click() + driver.find_element(By.XPATH,"//*[contains(text(),'Apply')]").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'Where to store?')]").click() + time.sleep(1) + driver.find_element(By.XPATH,"//*[contains(text(),'Xopero Storage')]").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'When?')]").click() + startAt = driver.find_element(By.XPATH,'/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-add-schedule/form/div[3]/div/mat-accordion/mat-expansion-panel[1]/div/div/app-monthly/div/mat-radio-group/div/div[2]/app-time/mat-form-field/div/div[1]/div/input') + startAt.send_keys('1111') + driver.find_element(By.XPATH,"//*[contains(text(),'Next')]").click() + driver.find_element(By.XPATH,"//button[@type='submit']").click() + + driver.find_element(By.XPATH,"//*[contains(text(),'Save&Run')]").click() + driver.find_element(By.XPATH,"//*[contains(text(),'Tasks')]").click() From 1436aa5a6c421f4718ae35941b3a402a18cb8994 Mon Sep 17 00:00:00 2001 From: Xaranti <85513286+Xaranti@users.noreply.github.com> Date: Fri, 20 May 2022 11:21:04 +0200 Subject: [PATCH 11/20] Create lunchin bat file --- lunchin bat file | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 lunchin bat file diff --git a/lunchin bat file b/lunchin bat file new file mode 100644 index 0000000..edce753 --- /dev/null +++ b/lunchin bat file @@ -0,0 +1,7 @@ +import subprocess + +filepath=r"D:\test\hello" +p = subprocess.Popen(filepath, shell=True, stdout = subprocess.PIPE) + +stdout, stderr = p.communicate() +print (p.returncode) # is 0 if success From f987c083f977a34fa91762caf4793d4aaf697023 Mon Sep 17 00:00:00 2001 From: Xaranti <85513286+Xaranti@users.noreply.github.com> Date: Fri, 20 May 2022 11:22:05 +0200 Subject: [PATCH 12/20] Update lunchin bat file --- lunchin bat file | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lunchin bat file b/lunchin bat file index edce753..f292d20 100644 --- a/lunchin bat file +++ b/lunchin bat file @@ -5,3 +5,10 @@ p = subprocess.Popen(filepath, shell=True, stdout = subprocess.PIPE) stdout, stderr = p.communicate() print (p.returncode) # is 0 if success + + +///////////////////////////////////////// + +from subprocess import Popen +p = Popen("batchfile.bat", cwd=r"D:\test\hello") +stdout, stderr = p.communicate() From dda72583480fb2512365b95fa16147a4f17e26a4 Mon Sep 17 00:00:00 2001 From: Xaranti <85513286+Xaranti@users.noreply.github.com> Date: Mon, 23 May 2022 12:39:49 +0200 Subject: [PATCH 13/20] Update lunchin bat file --- lunchin bat file | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lunchin bat file b/lunchin bat file index f292d20..96b4723 100644 --- a/lunchin bat file +++ b/lunchin bat file @@ -1,3 +1,9 @@ +import os +os.system(r"D:\Pyt\regresja\FileBackUp\FileGen\GenerateProject 0") <--- 0 to argument + + +/////////////////////////////////////// + import subprocess filepath=r"D:\test\hello" From 15e23c7bb8c2b45832df6de2be8d8d35d339f408 Mon Sep 17 00:00:00 2001 From: Xaranti <85513286+Xaranti@users.noreply.github.com> Date: Thu, 2 Jun 2022 21:35:47 +0200 Subject: [PATCH 14/20] RSA RSA --- code-Part1/Demo.py | 67 +++++ code-Part1/childWindow.py | 13 + code-Part1/chromeOptionsDemo.py | 14 + code-Part1/demoBrowser.py | 25 ++ code-Part1/e2eTest.py | 35 +++ code-Part1/explicitwaitDemo.py | 63 ++++ code-Part1/findElementsTest.py | 21 ++ code-Part1/framesDemo.py | 13 + code-Part1/geckodriver.log | 38 +++ code-Part1/jseDemo.py | 25 ++ code-Part1/locators.py | 23 ++ code-Part1/locatorsExtension.py | 17 ++ code-Part1/pytestsDemo.zip | Bin 0 -> 91689 bytes .../pytestsDemo/pytestsDemo/BaseClass.py | 18 ++ .../pytestsDemo/pytestsDemo/__init__.py | 0 .../__pycache__/BaseClass.cpython-37.pyc | Bin 0 -> 760 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 155 bytes .../conftest.cpython-37-pytest-5.2.1.pyc | Bin 0 -> 1489 bytes .../test_demo1.cpython-37-pytest-5.2.1.pyc | Bin 0 -> 730 bytes .../test_demo2.cpython-37-pytest-5.2.1.pyc | Bin 0 -> 1985 bytes ...st_fixtureDemo.cpython-37-pytest-5.2.1.pyc | Bin 0 -> 1056 bytes ...t_fixturesData.cpython-37-pytest-5.2.1.pyc | Bin 0 -> 775 bytes ...t_fixturesDemo.cpython-37-pytest-5.2.1.pyc | Bin 0 -> 1245 bytes .../test_logging.cpython-37-pytest-5.2.1.pyc | Bin 0 -> 891 bytes ...est_reportdemo.cpython-37-pytest-5.2.1.pyc | Bin 0 -> 1089 bytes .../pytestsDemo/pytestsDemo/assets/style.css | 163 ++++++++++ .../pytestsDemo/pytestsDemo/conftest.py | 19 ++ .../pytestsDemo/pytestsDemo/logfile.log | 7 + .../pytestsDemo/pytestsDemo/report.html | 284 ++++++++++++++++++ .../pytestsDemo/pytestsDemo/test_demo1.py | 26 ++ .../pytestsDemo/pytestsDemo/test_demo2.py | 40 +++ .../pytestsDemo/test_fixturesData.py | 17 ++ .../pytestsDemo/test_fixturesDemo.py | 17 ++ .../pytestsDemo/pytestsDemo/test_logging.py | 22 ++ .../pytestsDemo/test_reportdemo.py | 4 + ...emo.py_test_screenshot_on_test_failure.png | Bin 0 -> 77037 bytes code-Part1/uiControls.py | 28 ++ code-Part1/waitDemo.py | 30 ++ 38 files changed, 1029 insertions(+) create mode 100644 code-Part1/Demo.py create mode 100644 code-Part1/childWindow.py create mode 100644 code-Part1/chromeOptionsDemo.py create mode 100644 code-Part1/demoBrowser.py create mode 100644 code-Part1/e2eTest.py create mode 100644 code-Part1/explicitwaitDemo.py create mode 100644 code-Part1/findElementsTest.py create mode 100644 code-Part1/framesDemo.py create mode 100644 code-Part1/geckodriver.log create mode 100644 code-Part1/jseDemo.py create mode 100644 code-Part1/locators.py create mode 100644 code-Part1/locatorsExtension.py create mode 100644 code-Part1/pytestsDemo.zip create mode 100644 code-Part1/pytestsDemo/pytestsDemo/BaseClass.py create mode 100644 code-Part1/pytestsDemo/pytestsDemo/__init__.py create mode 100644 code-Part1/pytestsDemo/pytestsDemo/__pycache__/BaseClass.cpython-37.pyc create mode 100644 code-Part1/pytestsDemo/pytestsDemo/__pycache__/__init__.cpython-37.pyc create mode 100644 code-Part1/pytestsDemo/pytestsDemo/__pycache__/conftest.cpython-37-pytest-5.2.1.pyc create mode 100644 code-Part1/pytestsDemo/pytestsDemo/__pycache__/test_demo1.cpython-37-pytest-5.2.1.pyc create mode 100644 code-Part1/pytestsDemo/pytestsDemo/__pycache__/test_demo2.cpython-37-pytest-5.2.1.pyc create mode 100644 code-Part1/pytestsDemo/pytestsDemo/__pycache__/test_fixtureDemo.cpython-37-pytest-5.2.1.pyc create mode 100644 code-Part1/pytestsDemo/pytestsDemo/__pycache__/test_fixturesData.cpython-37-pytest-5.2.1.pyc create mode 100644 code-Part1/pytestsDemo/pytestsDemo/__pycache__/test_fixturesDemo.cpython-37-pytest-5.2.1.pyc create mode 100644 code-Part1/pytestsDemo/pytestsDemo/__pycache__/test_logging.cpython-37-pytest-5.2.1.pyc create mode 100644 code-Part1/pytestsDemo/pytestsDemo/__pycache__/test_reportdemo.cpython-37-pytest-5.2.1.pyc create mode 100644 code-Part1/pytestsDemo/pytestsDemo/assets/style.css create mode 100644 code-Part1/pytestsDemo/pytestsDemo/conftest.py create mode 100644 code-Part1/pytestsDemo/pytestsDemo/logfile.log create mode 100644 code-Part1/pytestsDemo/pytestsDemo/report.html create mode 100644 code-Part1/pytestsDemo/pytestsDemo/test_demo1.py create mode 100644 code-Part1/pytestsDemo/pytestsDemo/test_demo2.py create mode 100644 code-Part1/pytestsDemo/pytestsDemo/test_fixturesData.py create mode 100644 code-Part1/pytestsDemo/pytestsDemo/test_fixturesDemo.py create mode 100644 code-Part1/pytestsDemo/pytestsDemo/test_logging.py create mode 100644 code-Part1/pytestsDemo/pytestsDemo/test_reportdemo.py create mode 100644 code-Part1/pytestsDemo/pytestsDemo/test_reportdemo.py_test_screenshot_on_test_failure.png create mode 100644 code-Part1/uiControls.py create mode 100644 code-Part1/waitDemo.py diff --git a/code-Part1/Demo.py b/code-Part1/Demo.py new file mode 100644 index 0000000..015b666 --- /dev/null +++ b/code-Part1/Demo.py @@ -0,0 +1,67 @@ +#Implicit wait - +#Explicit Wait +import time + +from selenium import webdriver +#pause the test for few seconds using Time class +from selenium.webdriver.common.by import By +from selenium.webdriver.support import expected_conditions +from selenium.webdriver.support.wait import WebDriverWait + +#driver = webdriver.Chrome(executable_path="C:\\chromedriver.exe") + +driver = webdriver.Ie(executable_path="C:\\IEDriverServer.exe") +driver.implicitly_wait(5) +list = [] +list2 = [] +# wait until 5 seconds if object is not displayed +#Global wait +#1.5 second to reach next page- execution will resume in 1.5 seconds +#if object do not show up at all, then max time your test waits for 5 seconds +driver.get("https://rahulshettyacademy.com/seleniumPractise/") +driver.find_element_by_css_selector("input.search-keyword").send_keys("ber") +time.sleep(4) +count =len(driver.find_elements_by_xpath("//div[@class='products']/div")) +assert count == 3 +buttons = driver.find_elements_by_xpath("//div[@class='product-action']/button") + +for button in buttons: + list.append(button.find_element_by_xpath("parent::div/parent::div/h4").text) + button.click() + +print(list) + +driver.find_element_by_css_selector("img[alt='Cart']").click() +driver.find_element_by_xpath("//button[text()='PROCEED TO CHECKOUT']").click() +wait = WebDriverWait(driver, 5) +wait.until(expected_conditions.presence_of_element_located((By.CLASS_NAME, "promoCode"))) +veggies =driver.find_elements_by_css_selector("p.product-name") +for l in veggies: + list2.append(l.text) + +print(list2) +assert list == list2 + +amount1= driver.find_element_by_css_selector(".discountAmt").text + +driver.find_element_by_class_name("promoCode").send_keys("rahulshettyacademy") +driver.find_element_by_css_selector(".promoBtn").click() +print(driver.find_element_by_css_selector("span.promoInfo").text) + +amount2= driver.find_element_by_css_selector(".discountAmt").text + +assert int(amount1) > float(amount2) + +veggiesAmount = driver.find_elements_by_xpath("//tr/td[5]/p") +sum = 0 + +for v in veggiesAmount: + sum = sum + int(v.text) + +print(sum) + +assert sum == int(amount2) + + + + diff --git a/code-Part1/childWindow.py b/code-Part1/childWindow.py new file mode 100644 index 0000000..ae34a39 --- /dev/null +++ b/code-Part1/childWindow.py @@ -0,0 +1,13 @@ +from selenium import webdriver +driver = webdriver.Chrome(executable_path="C:\\chromedriver.exe") + +driver.get("https://the-internet.herokuapp.com/windows") +driver.find_element_by_link_text("Click Here").click() +childwindow = driver.window_handles[1] + +driver.switch_to.window(childwindow) +print(driver.find_element_by_tag_name("h3").text) +driver.close() +driver.switch_to.window(driver.window_handles[0]) + +assert "Opening a new window" == driver.find_element_by_tag_name("h3").text diff --git a/code-Part1/chromeOptionsDemo.py b/code-Part1/chromeOptionsDemo.py new file mode 100644 index 0000000..856d2c1 --- /dev/null +++ b/code-Part1/chromeOptionsDemo.py @@ -0,0 +1,14 @@ +from selenium import webdriver +from selenium.webdriver.support.select import Select + +chrome_options = webdriver.ChromeOptions() +chrome_options.add_argument("--start-maximized") +chrome_options.add_argument("headless") +chrome_options.add_argument("--ignore-certificate-errors") + + +driver = webdriver.Chrome(executable_path="C:\\chromedriver.exe",options=chrome_options) + +driver.get("https://rahulshettyacademy.com/angularpractice/") + +print(driver.title) \ No newline at end of file diff --git a/code-Part1/demoBrowser.py b/code-Part1/demoBrowser.py new file mode 100644 index 0000000..025d028 --- /dev/null +++ b/code-Part1/demoBrowser.py @@ -0,0 +1,25 @@ +from selenium import webdriver +#browser exposes an executable file +#Through Selenium test we need to invoke the executable file which will then invoke actual browser +#driver = webdriver.Chrome(executable_path="C:\\chromedriver.exe") +#driver=webdriver.Firefox(executable_path="C:\\geckodriver.exe") +driver = webdriver.Ie(executable_path="C:\\IEDriverServer.exe") +driver.maximize_window() +driver.get("https://rahulshettyacademy.com/") #get method to hit url on browser + +print(driver.title) +print(driver.current_url) +driver.get("https://rahulshettyacademy.com/AutomationPractice/") +driver.minimize_window() +driver.back() +driver.refresh() +driver.close() + + + + + + + + + diff --git a/code-Part1/e2eTest.py b/code-Part1/e2eTest.py new file mode 100644 index 0000000..a391e60 --- /dev/null +++ b/code-Part1/e2eTest.py @@ -0,0 +1,35 @@ + +from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.support import expected_conditions +from selenium.webdriver.support.select import Select +from selenium.webdriver.support.wait import WebDriverWait + +driver = webdriver.Chrome(executable_path="C:\\chromedriver.exe") +driver.get("https://rahulshettyacademy.com/angularpractice/") +driver.find_element_by_css_selector("a[href*='shop']").click() +products = driver.find_elements_by_xpath("//div[@class='card h-100']") + +#//div[@class='card h-100']/div/h4/a +#product =//div[@class='card h-100'] +for product in products: + productName = product.find_element_by_xpath("div/h4/a").text + if productName == "Blackberry": + #Add item into cart + product.find_element_by_xpath("div/button").click() + +driver.find_element_by_css_selector("a[class*='btn-primary']").click() +driver.find_element_by_xpath("//button[@class='btn btn-success']").click() +driver.find_element_by_id("country").send_keys("ind") +wait = WebDriverWait(driver, 7) +wait.until(expected_conditions.presence_of_element_located((By.LINK_TEXT, "India"))) +driver.find_element_by_link_text("India").click() +driver.find_element_by_xpath("//div[@class='checkbox checkbox-primary']").click() +driver.find_element_by_css_selector("[type='submit']").click() +successText = driver.find_element_by_class_name("alert-success").text + +assert "Success! Thank you!" in successText + +driver.get_screenshot_as_file("screen.png") + + diff --git a/code-Part1/explicitwaitDemo.py b/code-Part1/explicitwaitDemo.py new file mode 100644 index 0000000..76cdcbb --- /dev/null +++ b/code-Part1/explicitwaitDemo.py @@ -0,0 +1,63 @@ +#Implicit wait - +#Explicit Wait +import time + +from selenium import webdriver +#pause the test for few seconds using Time class +from selenium.webdriver.common.by import By +from selenium.webdriver.support import expected_conditions +from selenium.webdriver.support.wait import WebDriverWait + +list = [] +list2 = [] +driver = webdriver.Chrome(executable_path="C:\\chromedriver.exe") + +driver.get("https://rahulshettyacademy.com/seleniumPractise/") +driver.find_element_by_css_selector("input.search-keyword").send_keys("ber") +time.sleep(4) +count =len(driver.find_elements_by_xpath("//div[@class='products']/div")) +assert count == 3 +buttons = driver.find_elements_by_xpath("//div[@class='product-action']/button") +#//div[@class='product-action']/button/parent::div/parent::div/h4 +for button in buttons: + list.append(button.find_element_by_xpath("parent::div/parent::div/h4").text) + button.click() +print(list) + +driver.find_element_by_css_selector("img[alt='Cart']").click() +driver.find_element_by_xpath("//button[text()='PROCEED TO CHECKOUT']").click() +wait = WebDriverWait(driver, 8) +wait.until(expected_conditions.presence_of_element_located((By.CLASS_NAME, "promoCode"))) + +veggies =driver.find_elements_by_css_selector("p.product-name") +for veg in veggies: + list2.append(veg.text) + +print(list2) +assert list == list2 +originalAmount = driver.find_element_by_css_selector(".discountAmt").text +driver.find_element_by_class_name("promoCode").send_keys("rahulshettyacademy") +driver.find_element_by_css_selector(".promoBtn").click() + +wait.until(expected_conditions.presence_of_element_located((By.CSS_SELECTOR,"span.promoInfo"))) +discountAmount = driver.find_element_by_css_selector(".discountAmt").text + +assert float(discountAmount) < int(originalAmount) + +print(driver.find_element_by_css_selector("span.promoInfo").text) + +amounts = driver.find_elements_by_xpath("//tr/td[5]/p") +sum = 0 +for amount in amounts: + sum = sum + int(amount.text) #32+48+60 + +print(sum) + +totalAmount = int(driver.find_element_by_class_name("totAmt").text) + +assert sum == totalAmount + + + + + diff --git a/code-Part1/findElementsTest.py b/code-Part1/findElementsTest.py new file mode 100644 index 0000000..932f154 --- /dev/null +++ b/code-Part1/findElementsTest.py @@ -0,0 +1,21 @@ +import time + +from selenium import webdriver + +driver = webdriver.Chrome(executable_path="C:\\chromedriver.exe") +driver.get("https://www.makemytrip.com/") +driver.find_element_by_id("fromCity").click() +driver.find_element_by_css_selector("input[placeholder='From']").send_keys("del") +time.sleep(2) +cities =driver.find_elements_by_css_selector("p[class*='blackText']") +print (len(cities)) +for city in cities: + if city.text =="Del Rio, United States": + city.click() + break + + +driver.find_element_by_xpath("//p[text()='Delhi, India']").click() + + + diff --git a/code-Part1/framesDemo.py b/code-Part1/framesDemo.py new file mode 100644 index 0000000..628a313 --- /dev/null +++ b/code-Part1/framesDemo.py @@ -0,0 +1,13 @@ + +from selenium import webdriver + +driver = webdriver.Chrome(executable_path="C:\\chromedriver.exe") +#iframe, frameset, frame +driver.get("https://the-internet.herokuapp.com/iframe") +#frame id or frame name or index value +driver.switch_to.frame("mce_0_ifr") +driver.find_element_by_css_selector("#tinymce").clear() +driver.find_element_by_css_selector("#tinymce").send_keys("I am able to automate") +driver.switch_to.default_content() + +print(driver.find_element_by_tag_name("h3").text) \ No newline at end of file diff --git a/code-Part1/geckodriver.log b/code-Part1/geckodriver.log new file mode 100644 index 0000000..ba635a8 --- /dev/null +++ b/code-Part1/geckodriver.log @@ -0,0 +1,38 @@ +1572992575661 mozrunner::runner INFO Running command: "C:\\Program Files\\Mozilla Firefox\\firefox.exe" "-marionette" "-foreground" "-no-remote" "-profile" "C:\\Users\\Owner\\AppData\\Local\\Temp\\rust_mozprofilejNz7no" +1572992577423 addons.webextension.screenshots@mozilla.org WARN Loading extension 'screenshots@mozilla.org': Reading manifest: Invalid extension permission: mozillaAddons +1572992577423 addons.webextension.screenshots@mozilla.org WARN Loading extension 'screenshots@mozilla.org': Reading manifest: Invalid extension permission: telemetry +1572992577423 addons.webextension.screenshots@mozilla.org WARN Loading extension 'screenshots@mozilla.org': Reading manifest: Invalid extension permission: resource://pdf.js/ +1572992577424 addons.webextension.screenshots@mozilla.org WARN Loading extension 'screenshots@mozilla.org': Reading manifest: Invalid extension permission: about:reader* +JavaScript error: resource://gre/modules/XULStore.jsm, line 66: Error: Can't find profile directory. +1572992580400 Marionette INFO Listening on port 58063 +1572992580756 Marionette WARN TLS certificate errors will be ignored for this session +JavaScript error: , line 0: uncaught exception: Object +[Parent 12276, Gecko_IOThread] WARNING: pipe error: 109: file z:/task_1566864336/build/src/ipc/chromium/src/chrome/common/ipc_channel_win.cc, line 341 +[Child 12124, Chrome_ChildThread] WARNING: pipe error: 109: file z:/task_1566864336/build/src/ipc/chromium/src/chrome/common/ipc_channel_win.cc, line 341 +[Child 12124, Chrome_ChildThread] WARNING: pipe error: 109: file z:/task_1566864336/build/src/ipc/chromium/src/chrome/common/ipc_channel_win.cc, line 341 +[Parent 12276, Gecko_IOThread] WARNING: pipe error: 109: file z:/task_1566864336/build/src/ipc/chromium/src/chrome/common/ipc_channel_win.cc, line 341 +[Child 18904, Chrome_ChildThread] WARNING: pipe error: 109: file z:/task_1566864336/build/src/ipc/chromium/src/chrome/common/ipc_channel_win.cc, line 341 +[Child 189041573511128567 Marionette INFO Stopped listening on port 58063 + +###!!! [Child][RunMessage] Error: Channel closing: too late to send/recv, messages will be lost + + +###!!! [Child][MessageChannel::SendAndWait] Error: Channel error: cannot send/recv + +RN TLS certificate errors will be ignored for this session +1573510525471 mozrunner::runner INFO Running command: "C:\\Program Files\\Mozilla Firefox\\firefox.exe" "-marionette" "-foreground" "-no-remote" "-profile" "C:\\Users\\Owner\\AppData\\Local\\Temp\\rust_mozprofileLR4Aro" +1573510526869 addons.webextension.screenshots@mozilla.org WARN Loading extension 'screenshots@mozilla.org': Reading manifest: Invalid extension permission: mozillaAddons +1573510526869 addons.webextension.screenshots@mozilla.org WARN Loading extension 'screenshots@mozilla.org': Reading manifest: Invalid extension permission: telemetry +1573510526869 addons.webextension.screenshots@mozilla.org WARN Loading extension 'screenshots@mozilla.org': Reading manifest: Invalid extension permission: resource://pdf.js/ +1573510526869 addons.webextension.screenshots@mozilla.org WARN Loading extension 'screenshots@mozilla.org': Reading manifest: Invalid extension permission: about:reader* +JavaScript error: resource://gre/modules/XULStore.jsm, line 66: Error: Can't find profile directory. +1573510529795 Marionette INFO Listening on port 57932 +1573510529831 Marionette WARN TLS certificate errors will be ignored for this session +1573510542218 Marionette INFO Stopped listening on port 57932 +[Child 7836, Chrome_ChildThread] WARNING: pipe error: 109: file z:/task_1566864336/build/src/ipc/chromium/src/chrome/common/ipc_channel_win.cc, line 341 +[Child 7836, Chrome_ChildThread][GPU 3056, +###!!! [Child][RunMessage] Error: Channel closing: too late to send/recv, messages will be lost + + +###!!! [Child][MessageChannel::SendAndWait] Error: Channel error: cannot send/recv + diff --git a/code-Part1/jseDemo.py b/code-Part1/jseDemo.py new file mode 100644 index 0000000..f23f70b --- /dev/null +++ b/code-Part1/jseDemo.py @@ -0,0 +1,25 @@ +#Js DOM can access any elements on web page just like how selenium does +# selenium have a method to execute javascript code in it + +from selenium import webdriver + + +driver = webdriver.Chrome(executable_path="C:\\chromedriver.exe") +driver.get("https://rahulshettyacademy.com/angularpractice/") +driver.find_element_by_name("name").send_keys("hello") +print(driver.find_element_by_name("name").text) +print(driver.find_element_by_name("name").get_attribute("value")) +print(driver.execute_script('return document.getElementsByName("name")[0].value')) + +shopButton = driver.find_element_by_css_selector("a[href*='shop']") +driver.execute_script("arguments[0].click();",shopButton) + +driver.execute_script("window.scrollTo(0,document.body.scrollHeight);") + + + + + + + + diff --git a/code-Part1/locators.py b/code-Part1/locators.py new file mode 100644 index 0000000..82054c2 --- /dev/null +++ b/code-Part1/locators.py @@ -0,0 +1,23 @@ +from selenium import webdriver +from selenium.webdriver.support.select import Select + +#driver = webdriver.Chrome(executable_path="C:\\chromedriver.exe") +driver = webdriver.Firefox(executable_path="C:\\geckodriver.exe") +driver.get("https://rahulshettyacademy.com/angularpractice/") + +#driver.find_element_by_name("name").send_keys("Rahul") +driver.find_element_by_css_selector("input[name='name']").send_keys("Rahul") +driver.find_element_by_name("email").send_keys("Shetty") + +driver.find_element_by_id("exampleCheck1").click() + +#select class provide the methods to handle the options in dropdown +dropdown = Select(driver.find_element_by_id("exampleFormControlSelect1")) +dropdown.select_by_visible_text("Female") +dropdown.select_by_index(0) + +driver.find_element_by_xpath("//input[@type='submit']").click() + +message = driver.find_element_by_class_name("alert-success").text + +assert "success" in message \ No newline at end of file diff --git a/code-Part1/locatorsExtension.py b/code-Part1/locatorsExtension.py new file mode 100644 index 0000000..cd35793 --- /dev/null +++ b/code-Part1/locatorsExtension.py @@ -0,0 +1,17 @@ +from selenium import webdriver + +driver = webdriver.Chrome(executable_path="C:\\chromedriver.exe") +driver.get("https://login.salesforce.com/") +driver.find_element_by_css_selector("#username").send_keys("Rahul") +driver.find_element_by_css_selector(".password").send_keys("shetty") +driver.find_element_by_css_selector(".password").clear() +driver.find_element_by_link_text("Forgot Your Password?").click() +#//tagname[text()=’xxx’] +driver.find_element_by_xpath("//a[text()='Cancel']").click() +print(driver.find_element_by_xpath("//form[@name='login']/div[1]/label").text) +print(driver.find_element_by_css_selector("form[name='login'] label:nth-child(3)").text) + + + + + diff --git a/code-Part1/pytestsDemo.zip b/code-Part1/pytestsDemo.zip new file mode 100644 index 0000000000000000000000000000000000000000..a5727af8b73d443682efcb3db24e2b83163935b5 GIT binary patch literal 91689 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 T%V$_h;Kv%cex+yv5di%k<7w8C literal 0 HcmV?d00001 diff --git a/code-Part1/pytestsDemo/pytestsDemo/BaseClass.py b/code-Part1/pytestsDemo/pytestsDemo/BaseClass.py new file mode 100644 index 0000000..4d2031e --- /dev/null +++ b/code-Part1/pytestsDemo/pytestsDemo/BaseClass.py @@ -0,0 +1,18 @@ +import inspect +import logging + + +class BaseClass: + def getLogger(self): + loggerName = inspect.stack()[1][3] + logger = logging.getLogger(loggerName) + fileHandler = logging.FileHandler('logfile.log') + formatter = logging.Formatter("%(asctime)s :%(levelname)s : %(name)s :%(message)s") + fileHandler.setFormatter(formatter) + + logger.addHandler(fileHandler) # filehandler object + + logger.setLevel(logging.DEBUG) + return logger + + diff --git a/code-Part1/pytestsDemo/pytestsDemo/__init__.py b/code-Part1/pytestsDemo/pytestsDemo/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/code-Part1/pytestsDemo/pytestsDemo/__pycache__/BaseClass.cpython-37.pyc b/code-Part1/pytestsDemo/pytestsDemo/__pycache__/BaseClass.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e03a5d0e533f5f453346197bad5ca01caaf6a3c1 GIT binary patch literal 760 zcmYjPJ8#=C5avU&W!V9Orc1V4P|P6 zh%@#N^v7`RY>Xi}#sRMp6p5%LE?Tk&5^>30mhFrLsBtO) z5^SL|AJNH=alj`8LpJmgTi8e0eR59?+whV;(tC!?lN=dG=1UKmSMp7(L`F%;HtiBu zD;5}b)2TTM`;)Dc+d7?fH!bF~MXC<*zkb^v2uRE#Q$sj7>JL)&U8T9G-Glz1q5VOo z0K^=_hM{dQa#*UwSRaf?zS%aGnlJLX?aYe6&a5f_i|ALl$$zKgqv;hW z4bzW5a;2x2tK?ef>{1su*f*eWu8aJO0)uT&mn(w|PE=M*pKj=IxzYjFYTJJ-Xg|j(ytq1aCQrV|Q+GY{NLt3VD}0-izbgJ5e2O99NaAR$ss#YH0V2+?xPL i0$TY)uHBSwJ8<(alH7K+%e29}TI;>LYw!>P8u0&8(!&D) literal 0 HcmV?d00001 diff --git a/code-Part1/pytestsDemo/pytestsDemo/__pycache__/__init__.cpython-37.pyc b/code-Part1/pytestsDemo/pytestsDemo/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..49a1bc436b5920da029eb41549093502f66fbccf GIT binary patch literal 155 zcmZ?b<>g`kf;hoVu^{>}h=2h`Aj1KOi&=m~3PUi1CZpdI z<6oYaS`-sdnVgYWlp9c#pOu)Ii}awmlTC6D*qTH4V_mLC98ML`IS=Q36TF zkIJX)wU?ZF=)pPmH}s$I+Ef3+o;sw9qyulURw04!(y420kjk^YF(xKkekz-4BrjGbk`5^aioOK6yfjDnFG6pIX zw?N$j)!p<=aCZ*vK1FL^?X><4#;EnhE$y}b6SNLmZ?oIt$=+ta4elTYkbIkfgi4H2Y@3dO3CWoXYRp6L!-C_%KBlCsnt$<(aT;he~Y zQC>Ntk;ci&8#X*!{XC|{^~t!XvPg>bxc^-CBT}m4{zE|hNUCMYj{Eb1s(keMXJ0gn zuX0voxf;EE`6WF1QO(n`NT=oxr}cbTH;jLx@cE&RGJf0_MydbeWch2XdPB^KUHS;?X?}MRtuTMu8KS(Cz#kX_L#KrkC&55YaMLl7ulJHh} z%}r|*JiFL>ldoA-Ul?GF?_sml&;AKR%(xAwg5KH2;DZxsJRyG{`#8kA&Jph6BYX(7 zhaKP@V(}r!?`O%(l*#lIw%mt9p$%@4>0yeXd-2)8(f)P-<0l6F2gnj46O$-Rsb_OF zu5G5`14A9bVF>BKfv|m>nY~~4j^6{80*BL394S13L8i_xm;et#aL-nc0k||50QWYM zAzOgg_yDeSrpP6L-4K-zT=5ZD62@QbpIU`&JpYYM2bZFrLm@tfkJ6xqJOh?}Lm!5h zv!a9=NWJ^2Stj?dXUP`&A(5c0ikc4vn+s?T-Mwd-Hrw)gplmBdL>x+1GG5Fo8=UsH z5*x1eDk7$OC$H=2T$nBtwni2&9b6R))2cSM|4k+wS2dlL?8Ma4)-XheXxEh7ee^W+ F{swxorjh^v literal 0 HcmV?d00001 diff --git a/code-Part1/pytestsDemo/pytestsDemo/__pycache__/test_demo1.cpython-37-pytest-5.2.1.pyc b/code-Part1/pytestsDemo/pytestsDemo/__pycache__/test_demo1.cpython-37-pytest-5.2.1.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e184f32996d8a060fa0af733e0710794a3878662 GIT binary patch literal 730 zcmaJ;v2NQi5G7?%RvZ~{vn5kjF9y06MG(YA-KDO9q>G@yP(>z|BZfq)FTxePKO@AV z9-*Z4V@8{kAPz(@Z_h*S@z$C=(0I?q9qx1H;(Z?Q_L{^Ir{|;}zF&XCiY-921G zTq;7Rk?(=p?pW=OWA;rHh3r$qYRD^Xff9OA{~_RG`Rmu=r{t#+ppqZUN6P#W)ELt2J*Bs&}NAV8m4 zxUv7ud>4(RxPBHsK zPO%;WP3}>%L)3n&+KZL-jTjY+GLTB0fn1_c|IW}ne7E8NFE`W_I<`^QgufPffeI=U zoz|=AHaeU(iVjkRt#vM|0f;5!TA00U%CtAR4qkRoPQe5XG=7=FP0Um&Z-mp?u-mIN jFTlRq@$XD*zZ{%&;pbBFMIlaXO4%_(azH}A$9n89e~qps literal 0 HcmV?d00001 diff --git a/code-Part1/pytestsDemo/pytestsDemo/__pycache__/test_demo2.cpython-37-pytest-5.2.1.pyc b/code-Part1/pytestsDemo/pytestsDemo/__pycache__/test_demo2.cpython-37-pytest-5.2.1.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a316bcff9cff047eabd61d200055ef64007bf55f GIT binary patch literal 1985 zcmc(f&2Jnv6u|BI+S$!+zS<;hk;+i1QbwQ%k|q>HqK1^Jrx4L1q*bbsv-T#F%*V=} z5Oy_tX?lbM_a3@Ou5jlM;7{;@3#a@GJ@KArH`+>w6B09;=Vw39`>_42LvaaCZtVGYo)eDC`p~RODl`l_Jns@JN3E6?N{WIw(H#C?km!6 zaQcjd-WB*D`yG_{)W+W)wCZ;doDK=MhO{IlJ+p>ZX>oGq%g5a2PC`;Tv>}qs-2`F} z9ZE{4w7GYQ`P8`2>p$U`rG71(H!g3KR+sV_^wqUS4sRCTo7#w+c}jxaFUg3?60|yM znFV&#>4@^yYipSdUFbLXEcEAA2%j(An8K)6%)ofF^hWfOzJ$mQ8A8UKKz$4Q+I=dL zByU?!V@aW)km@@J{X(c>S1BQjZ^VU+3-KM3S)3h%wRHh%B!1{6aVIVYo6JlDTTq;c z;Cq&wi(o&`#799d5lo5T9KL(itRPm#c5m=x@AJcN!M{5E`XUqZ@Sxv0VKP0C`Kjm> z3i`!Ko;`;&!1H0xB%~gTG(W`DA`aU6TCab#f+^eD@32A~=d!Q;Zk&jWr9yj2oQW(C z>04`iJEVif`>VbF$DsXN0)?@<`YtLZh>eqEW)%nDfVUn-r zR8byGceZ{Z@)kIG`ycJGUNBqUjioB!d>l)b-T?OsV-VY+4)Nh_!g~{r_7k#9W{JE5 zwrgs!BqY~R`zI(9YPk)>0)H!HXamK-X6XRMZs{6|pW|I%DE5G2hkJ(N8W3A6Jzg^u z1H-&wD0bB!z?lpDxg%!>}wmi^`YP3bI_j$ zniopn&|DwWT%V>Hh_>N#hmN6oasLXB*OiCD0x>4rY+gvs_Wj@B-i5S6TVje5_eT0S zKxN%DgS)E}T0bNcnwWMvoYP-obEjMXM#SRCg?N6 zPbF?+ge613GttR2z9$7#xyK}b4@?Tzkx-z(aPTe*`xOfxz>IK4`;(i*l%{V_uBi%h zShh7;-SxVDJ)~>nF|#n*tF9~Uq)eV^SEc!xFsMn4F_ks4DNXAB7irGV6S0Hqsc@5h KvPgV;-v1k%k0wh1 literal 0 HcmV?d00001 diff --git a/code-Part1/pytestsDemo/pytestsDemo/__pycache__/test_fixtureDemo.cpython-37-pytest-5.2.1.pyc b/code-Part1/pytestsDemo/pytestsDemo/__pycache__/test_fixtureDemo.cpython-37-pytest-5.2.1.pyc new file mode 100644 index 0000000000000000000000000000000000000000..21378a85d09e172b20167471427f8316532a89c8 GIT binary patch literal 1056 zcmb`G&2H2%5PNb^4qPInmAZRF2(2iB3tB1_gcJo?A$Dm>{%SkgZjWpq z1dd$$IKK8$UV#%c30+o{Lxt+dJ(^hpA9-!f8Qb z+O1Y;TZEF*iCx<7c(EtEJbRhT@qWIa_gMLb{{HsxXV4TT|R(dzS()1pXyeM7ow~)AnyjQ7;F!w8iCM2 zy{5geo4nHi+_&PL-YxI!|9EHP+w#s9 zk!O6ysAnz+;vDQjn}KjDO35`?6gY! Y?mE?7`Y%G`Kkc)7hJR6yN$vycF9oF(Pyhe` literal 0 HcmV?d00001 diff --git a/code-Part1/pytestsDemo/pytestsDemo/__pycache__/test_fixturesData.cpython-37-pytest-5.2.1.pyc b/code-Part1/pytestsDemo/pytestsDemo/__pycache__/test_fixturesData.cpython-37-pytest-5.2.1.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3bbc0896db132f71c0d1e03e27f23a710c11f195 GIT binary patch literal 775 zcmZ8f&2AGh5FUGf>LeS4s&eRo2goG{goK0;ikc!WB~$_~tAJ%JisE z6GjblVT@x^SaDGaIq~FfQ3L}tbAnFQEu>TuN$(*IWPrs&mwZ&lzPS~}JXg;qeurNH zT8K78GtbejU;|tDL05D`Rz#9h*b)N&BHBcjB7=C1j0CJ6j5I0(558(IaIKlL7u9U0 zvgfw zFt%4!=?BQl*?7LRh|IYvsCcz$ah+8%vshu8<*J2;7={iABaiU8 zd+Lkr)ad{J{Rs79oR^|doVzyXMI{%x#|h`(7b0&M-NlOa1P3nhIWK99X1pRSsN-JZ z*w;mt;|#_ngZYy0qf_3@)W<7U+GbVR*Xl-RR=L(b<&Ji_Hg2w47TU!POrIR6(%=6t r+Mn;jLg;URNc@))BYB;@7%Fh&8)Beg_<@x2FJi?5}c5~(csKl literal 0 HcmV?d00001 diff --git a/code-Part1/pytestsDemo/pytestsDemo/__pycache__/test_fixturesDemo.cpython-37-pytest-5.2.1.pyc b/code-Part1/pytestsDemo/pytestsDemo/__pycache__/test_fixturesDemo.cpython-37-pytest-5.2.1.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e39299b70091139060e394abb083d1342617d300 GIT binary patch literal 1245 zcmb`G&2AGh5P>svQNqS8m1dg0} z4<5i*PP_sqW_Ft>>H$Snz4FX>ydHle&%786x^DdQ<1b3cZ?ZQWuxBt83Qjo9NJJZL z<+epA$(_ih?T#0D!n^Rl1>E{hUlVR~=ZbJ=V{K^E;q)CDx_=-FnHyILT~`S%w!;Er z22(u+A(~4fi&Ji0k;raCMGkkl2Wyx6JOJ(S4g~F*-g}|+t5uv=nMfdmW}wEPCookX zga-NzMOHXu%`YFP;WEv#P^?5!YY{3fDix+hc$ThoEyYWbmtijSdC7;=xRp!`4Thsc zcJ_lv4?_NZbMkEQK?$iAZ*-9?SexmKP$?3f6GEK)kg0yr|Y1EQNs=XtC>? z8qcU&o1=X%{^lb*W=;*ho}AIfV9WEyd@UEkV+R+lX5GN%iOyOG46tU zi~Hz*xZ}I!o!pLhGB}iXa<{zG+wo414&|NBhrS6IE8<)*X1a{!C9gBI`;2|90<*uj6M*E0thmcj^ z#9!bZj@%JH##c`K1x}1Nn>G@*JoC-V{>I*Y)oi+lzkYuBW)bq6>T*s`J3&FIW9y0`gWK25o$hw5 zZEpaN{XxVNeD=Q={gd%~2||wFE)x*rt5q;%BEAyo3<4$5R?{@O0jaRD@qDEa$=494 zV}tynxV?#{g>| zMBD*I5Wx}Z;CwY=(?A%-R;Pp!F^KsEb;<<4L9R82T+|M*Uf^*+Y>)#G@e@>r&Y;o^ z>+hzRm{TLenQ>xF&CDd|#NlmXky3_D)zRv`i%7>+6-7c*G-w5ptwGwi`B;ASW+RM3PHJiO-DSG^u5oM zFzEwY8-eN3PiYhep`7gac^Y61IiQV?el(eM`1z}=Hhds)pGG<<@VileBTv~R;!`SZCAKP$Ap+x+mreQ zQH|}oLI-!|9Kci2yS35e?``=g}|3SApyK{~U$7nU6;VoYF)LnDkiU<)NM*Mng{Z6%!kvkWq!ZX~FO0 zpk;Vh!QO + + + + Test Report + + + +

report.html

+

Report generated on 31-Oct-2019 at 18:17:52 by pytest-html v2.0.0

+

Environment

+ + + + + + + + + + + + + + + +
JAVA_HOMEC:\Program Files\Java\jdk1.8.0_211
Packages{'pytest': '5.2.1', 'py': '1.8.0', 'pluggy': '0.13.0'}
PlatformWindows-10-10.0.17763-SP0
Plugins{'html': '2.0.0', 'metadata': '1.8.0'}
Python3.7.4
+

Summary

+

1 tests ran in 4.27 seconds.

+ 0 passed, 0 skipped, 1 failed, 0 errors, 0 expected failures, 0 unexpected passes +

Results

+ + + + + + + + + + + + + + + + +
ResultTestDurationLinks
Failedtest_reportdemo.py::test_screenshot_on_test_failure1.54
+
screenshot
+
browser = <selenium.webdriver.chrome.webdriver.WebDriver (session="b6c20dc6275c03e764605d5e0e03700c")>

def test_screenshot_on_test_failure(browser):
# driver = webdriver.Firefox()
browser.get("https://google.com")
> assert 2 ==3
E assert 2 == 3

test_reportdemo.py:4: AssertionError
\ No newline at end of file diff --git a/code-Part1/pytestsDemo/pytestsDemo/test_demo1.py b/code-Part1/pytestsDemo/pytestsDemo/test_demo1.py new file mode 100644 index 0000000..8bcbfec --- /dev/null +++ b/code-Part1/pytestsDemo/pytestsDemo/test_demo1.py @@ -0,0 +1,26 @@ +# Any pytest file should start with test_ or end with _test +#pytest method names should start with test +#Any code should be wrapped in method only +import pytest + + + +@pytest.mark.smoke +def test_firstProgram(setup): + print("Hello") + + +@pytest.mark.xfail +def test_SecondGreetCreditCard(): + print("Good Morning") + + +def test_crossBrowser(crossBrowser): + print(crossBrowser[1]) + + + + + + + diff --git a/code-Part1/pytestsDemo/pytestsDemo/test_demo2.py b/code-Part1/pytestsDemo/pytestsDemo/test_demo2.py new file mode 100644 index 0000000..9bfd84c --- /dev/null +++ b/code-Part1/pytestsDemo/pytestsDemo/test_demo2.py @@ -0,0 +1,40 @@ +# Any pytest file should start with test_ or end with _test +#pytest method names should start with test +#Any code should be wrapped in method only +#Method name should have sense +# -k stands for method names execution, -s logs in out put -v stands for more info metadata +#you can run specific file with py.test +# you can mark (tag) tests @pytest.mark.smoke and then run with -m +#you can skip tests with @pytest.mark.skip +#@pytest.mark.xfail +#fixtures are used as setup and tear down methods for test cases- conftest file to generalize fixt +#fixture and make it available to all test cases (fixture name into parameters of method) +# datadriven and parameterization can be done with return statements in tuple format +#when you define fixture scope to class only, it will run once before class is initiated and at the end + + +import pytest + + +@pytest.mark.smoke +#@pytest.mark.skip +def test_firstProgram(): + msg = "Hello" #operations + assert msg == "Hi", "Test failed because strings do not match" + + + +def test_SecondCreditCard(): + a = 4 + b = 6 + assert a+2 == 6, "Addition do not match" + + + + + + + + + + diff --git a/code-Part1/pytestsDemo/pytestsDemo/test_fixturesData.py b/code-Part1/pytestsDemo/pytestsDemo/test_fixturesData.py new file mode 100644 index 0000000..a8343b4 --- /dev/null +++ b/code-Part1/pytestsDemo/pytestsDemo/test_fixturesData.py @@ -0,0 +1,17 @@ +import pytest + +from pytestsDemo.BaseClass import BaseClass + + +@pytest.mark.usefixtures("dataLoad") +class TestExample2(BaseClass): + + def test_editProfile(self, dataLoad): + log = self.getLogger() + log.info(dataLoad[0]) + log.info(dataLoad[2]) + print(dataLoad[2]) + + + + diff --git a/code-Part1/pytestsDemo/pytestsDemo/test_fixturesDemo.py b/code-Part1/pytestsDemo/pytestsDemo/test_fixturesDemo.py new file mode 100644 index 0000000..e057314 --- /dev/null +++ b/code-Part1/pytestsDemo/pytestsDemo/test_fixturesDemo.py @@ -0,0 +1,17 @@ +import pytest + + +@pytest.mark.usefixtures("setup") +class TestExample: + + def test_fixtureDemo(self): + print("i will execute steps in fixtureDemo method") + + def test_fixtureDemo1(self): + print("i will execute steps in fixtureDemo1 method") + + def test_fixtureDemo2(self): + print("i will execute steps in fixtureDemo2 method") + + def test_fixtureDemo3(self): + print("i will execute steps in fixtureDemo3 method") \ No newline at end of file diff --git a/code-Part1/pytestsDemo/pytestsDemo/test_logging.py b/code-Part1/pytestsDemo/pytestsDemo/test_logging.py new file mode 100644 index 0000000..7131cf5 --- /dev/null +++ b/code-Part1/pytestsDemo/pytestsDemo/test_logging.py @@ -0,0 +1,22 @@ +import logging + + +def test_loggingDemo(): + logger = logging.getLogger(__name__) + + fileHandler = logging.FileHandler('logfile.log') + formatter = logging.Formatter("%(asctime)s :%(levelname)s : %(name)s :%(message)s") + fileHandler.setFormatter(formatter) + + logger.addHandler(fileHandler) #filehandler object + + logger.setLevel(logging.CRITICAL) + logger.debug("A debug statement is executed") + logger.info("Information statement") + logger.debug("A debug statement is executed") + logger.warning("Something is in warning mode") + logger.error("A Major error has happend") + logger.critical("Critical issue") + + + diff --git a/code-Part1/pytestsDemo/pytestsDemo/test_reportdemo.py b/code-Part1/pytestsDemo/pytestsDemo/test_reportdemo.py new file mode 100644 index 0000000..e41d0fa --- /dev/null +++ b/code-Part1/pytestsDemo/pytestsDemo/test_reportdemo.py @@ -0,0 +1,4 @@ +def test_screenshot_on_test_failure(browser): + # driver = webdriver.Firefox() + browser.get("https://google.com") + assert 2 ==3 \ No newline at end of file diff --git a/code-Part1/pytestsDemo/pytestsDemo/test_reportdemo.py_test_screenshot_on_test_failure.png b/code-Part1/pytestsDemo/pytestsDemo/test_reportdemo.py_test_screenshot_on_test_failure.png new file mode 100644 index 0000000000000000000000000000000000000000..ac1b83f71a0f2c04e09480e79631b87484715a37 GIT binary patch literal 77037 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 Date: Thu, 16 Jun 2022 22:40:15 +0200 Subject: [PATCH 15/20] e2e --- Tests/__init__.py | 0 Tests/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 157 bytes Tests/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 155 bytes .../conftest.cpython-310-pytest-7.1.2.pyc | Bin 0 -> 1222 bytes .../conftest.cpython-39-pytest-7.1.2.pyc | Bin 0 -> 902 bytes .../test_e2e.cpython-310-pytest-7.1.2.pyc | Bin 0 -> 1965 bytes .../test_e2e.cpython-39-pytest-7.1.2.pyc | Bin 0 -> 1943 bytes Tests/conftest.py | 32 ++++++++++++++++ Tests/test_e2e.py | 36 ++++++++++++++++++ main.py | 16 ++++++++ pageObjects/CheckoutPage.py | 19 +++++++++ pageObjects/ConfirmPage.py | 0 pageObjects/HomePage.py | 15 ++++++++ .../__pycache__/CheckoutPage.cpython-310.pyc | Bin 0 -> 1129 bytes .../__pycache__/HomePage.cpython-310.pyc | Bin 0 -> 829 bytes utilities/BaseClass.py | 12 ++++++ .../__pycache__/BaseClass.cpython-310.pyc | Bin 0 -> 843 bytes .../__pycache__/BaseClass.cpython-39.pyc | Bin 0 -> 381 bytes 18 files changed, 130 insertions(+) create mode 100644 Tests/__init__.py create mode 100644 Tests/__pycache__/__init__.cpython-310.pyc create mode 100644 Tests/__pycache__/__init__.cpython-39.pyc create mode 100644 Tests/__pycache__/conftest.cpython-310-pytest-7.1.2.pyc create mode 100644 Tests/__pycache__/conftest.cpython-39-pytest-7.1.2.pyc create mode 100644 Tests/__pycache__/test_e2e.cpython-310-pytest-7.1.2.pyc create mode 100644 Tests/__pycache__/test_e2e.cpython-39-pytest-7.1.2.pyc create mode 100644 Tests/conftest.py create mode 100644 Tests/test_e2e.py create mode 100644 main.py create mode 100644 pageObjects/CheckoutPage.py create mode 100644 pageObjects/ConfirmPage.py create mode 100644 pageObjects/HomePage.py create mode 100644 pageObjects/__pycache__/CheckoutPage.cpython-310.pyc create mode 100644 pageObjects/__pycache__/HomePage.cpython-310.pyc create mode 100644 utilities/BaseClass.py create mode 100644 utilities/__pycache__/BaseClass.cpython-310.pyc create mode 100644 utilities/__pycache__/BaseClass.cpython-39.pyc diff --git a/Tests/__init__.py b/Tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Tests/__pycache__/__init__.cpython-310.pyc b/Tests/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2f58d94784fccdb8745c8728d62bc29a095d6e81 GIT binary patch literal 157 zcmd1j<>g`kf-7zFlR)%i5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!H6vsFxJacWU< zOhjT)VqQsROh9FFMq*KJKv8~HYH~?&OhIKyMt&ZY8xxXR3>1rx&&g`kf-7zFlR)%i5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!H6vsFxJacWU< zOhjT)VqQsROh9FFMq*KJKv8~HYH~?&OhIKyMt&ZY8xxXR3>1rx&&Ty?M=eliE-DVyN z5(u{W1f*oiFL{N;iZ4K71JyP}SzJ8oa@FaYuC8;+#bD5L==uEZWd6~0oG&&w{}ATv z(9%doI+A5h#F{r(E_axtyvS$mP7npO!?TVGqp-o;tgCuaukpR?g6c>8#`m*<8b%xB z2eR|Qi8diPyeLE2J!Y~eFMM#`vuI1QC(fw8 z-I`;u(15dCD5!mH3WPd{6D$<0hY4imwt=PDP5@!#)`5s^!MY=1UsRc?J)2^0E~G3< zyGKD#3ZyeXIXIy5-*|gFGD(sD3a3v&6Gq+b z8}i2Gs@|joa%X2ny0$mlq{l+m`+*ze)_$A`t*O4R67# zWpCIK(eoe2EyE98OVcrX!}EYppU^8g>pDmL#FN1(W7hLeX)2C55gW`p(s|xQC!s|f zYCC&%|2(nSp^EFji3jTO0EOCqlxCo}|5@JtcQkF;Zgn5S5=JcApjTWOG0$LD3X?>g z{S;xpSgt3DF{QpUnV?9jOebK>O2k5fT8-mEO+)X`4(C;xnKajRf2Ul{&Z29x zR{Ak13uxzSjIhAe0FB&l$lj{Odi3XZQjn&waidT}26b`ord-BjfS z*Pc1j9{EeTa^f#=Vw{Dl2e6g#d^3~r%r|DE(U9PJ{Po-HiATr}2d=LUf?fQ~0tF|W zN)prd^i;}cjbl(N! zITuzGxoP}NGGox|o2)=Lbs7IGY?ZjyGW^Uo3QHE0Q|_J9PxOplc)W8-DM77siA|o- zGqUKWJ}2*5bP+f!Cs=6r;Pm1CPI9P=6V24tDw3U22wDk-;?TX;*t3?6=9A z&I#Cftk_B@aSG{DLPM;@=w3CV9^^ z%dJQb>uk=n!j2ZmsY%M(&WrpHOx|DulOWB<7PU!PH=zMrm3z8aVww%iX+jjl3+a&d zaR*e75l6S0{;U$x3Y<;2Th{3nx|8A^E*s7Zw42^U!%_(Wx-=tk!Pw@%?{T{UQAg#McAp literal 0 HcmV?d00001 diff --git a/Tests/__pycache__/test_e2e.cpython-310-pytest-7.1.2.pyc b/Tests/__pycache__/test_e2e.cpython-310-pytest-7.1.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b91eaaea8e237d340e38c8881cc1c86384bd7da5 GIT binary patch literal 1965 zcmZ`)&2Jk;6rWkI?e%({#Ez4ufJ79a!ANzWr5q4NY2830N)i#HM$<&A_0BliWIx=Q zaau=f3DKUoaN*d4eL;dhX|A05FK~f3>o_t{W;M_6{ocHp=l3y_R4O)t@oN3|PLN0F z4=v0N6NF8e;wK;!Q5+(IvtJ|183?1uBzZj16i5LyMp%q2Vr5t^EJZf4Gu{l#kwct} z&xe(0j?8C#AzX;6q?+-?uof+n#f-PYdbC8AF!~zN6186J%sLM;=&=__02bNv9`hxmuAjs-kU3v6*ES=ia92=7rS6G?m0dr_!j4^mHs?g$uyR?}D z`QJ7+wf=+6)6yF-du)K8MOq$Osg)Mb(Xf=3#IJH;RHaT@>S9{ac-I)4fYnlKjOmE(SfFe`PGAp-mTPHMIi_d|58Tifd_k3=#Yhiqb?wYgnQP z5>VTD{TGbaI{L)EAA0^-hjBi*Slig>^rcMVC!4-b{N44Aj8|da6n)=kLaZN=qM!6* z$pp<=v?#>NH>&abR|T_Bz0`RbIp+2cXv@xl7h#rzXF=&`%&qTh)E3Bbye z?5vOOu6rTla`veG$*E9tMi4jfMeTzRdxK9JVl{|YHG8`uR7tYu@>@^(Ck=z-K&{E` zi#c!~cFUICX$TG8X{>NvV5%_b2x5toq_-_uL@LKjwmeSTfee{Yrrz@k{3=N#<0|im zfqzD^tcfN7kTL*3Er~Q3*f9ug!tG)Z3vNwAJ3GLx}Tvc7)3qzN)9`}=|=W(!eh1X>o zQ4XwhJN+P(K`c}uOklB4D=z%2en>Mb_c%;CUg*YN#MIoqEF{q0Tbw6cExO%=N1k+{ z|3feKbmKQ1WeOH{iFI<>@WjcI2!FT-?N0JOgh?nI5L0u+(zFfX;&Zy1%G#$%=s%tn zZcT*AfuGI_pZ$jT8kqjM+4}tOd&rqMJn*;|%iwTt;GcLr+T+P7+)v^V0&|kYm*Szm zL&RYgDt3!Cdjn-n1?`Hs0mQ}@d}c-qKo_v_gJaZk^aM^qYj{(=-lDGbU6^B<4DPyZe7W*;?;jLhzdG${4f;O+~I@#@H yDQixjjjZv=%B*VINBR}v7FcE>nhB(?3a+E6tS=_<|5D#rq6TCQJOB9VxxWDbK|8Vl literal 0 HcmV?d00001 diff --git a/Tests/__pycache__/test_e2e.cpython-39-pytest-7.1.2.pyc b/Tests/__pycache__/test_e2e.cpython-39-pytest-7.1.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8e5505cba70166459a2fc4177cfc003b75e5f734 GIT binary patch literal 1943 zcmZ`)&2Aev5GJ{+)k>E9C&y0G05yW9u8Kx(lctBFEgU;W8#Hx-*hSK{f(5mt>b3Vr zAt@&kRzT6@*h5Y|6{vOWi}WFQ?a8muOETQG453N6Aa~~DaE3EO4r#q!MbJ9G|JnJw zgwQ{RnQk^P8_=bIfgy$?V#e_tm?2R)c0D)8tf&%Ky=qR|(M(+P zYB^ns>hY{Mm(xx(A1`EH)v93Jh9VWtKE`TAM z0~qU%c;`+IJ))rkpuwN_c%V4*gEV2G3e!ZIrJGdpt%yn)7;V#y0J8yIF2TTa-#o%F zBQKF>F$;EJ>+&9#>VCol3^J2814J467IgU=%w*^gonS={Er!SB#2!O%&ae_-WK2ew zStF9+JLt)ck(Ci~ogYx@3&UcvL#K3fNnE%B=ntX0h3KU~^*vzBp`tRL;to zbBsoA=Dx!67d3Y>&lWPbi`k-?0lPL}3t4%LSwk(JG{)!{f#gF#mojIJUt!VCC4f!{ zYp|t1$TAvL*afznRYDAORb2pyZYmUVztv(DoutfbU!es2Xu8* za=j~>GRbIF=c3OUk!R3TP=V!(=R2Yi7i!wxZeiNok}zrF;o`NAdV|lJ zay3j=4SBOEbw%;#>IbTVgC_ATm^Q=B;Vd`_+H$d5O=-Ye%@yqw_fFTk;DXO19&_-> z0#|fxYj@Y*-M+WIwRiuaE(K8-9C>8(Cv6)Gy7c(L?Y-|bxqC-fB!|UEd?1A>DxPDa z5=NSAZ|V1Xg2Qyc{j@vL??-7s;VSFOy}LW#`+M7u_jGlmH&AdHeJb>VAJ8cB1@DO< zjeAsZUGXLDa)am^Ncx?A7^yIk+A+E!sW19)7Wxs(SNT6jX@^FBLSwFHZ|9yv!Ppie z6}sVfQxQ|;Lq&;bLQN@Y&S+cmsOy!?L6RDWo^2@4HRGP~w>$|>-MBboHc^E1(`n{L z!4wugpJu-J3yBY4>AxFWU$%dQT*&rgDrlm@_JcuiKt=pOq=!)AWE&!JkS1qr+mtBT z&SS%G@K$f2-3e0zeey#X5Lv?W*v2k=4)n`p36N!6!?Uk#pv<>OhVw=jl)KhM!4A|w z*U#hR`?~7;amxA;2fF6_Px~}75%hgwY~;J28m<}4)Jb#jrKz?q$@ykOyOaEgD}d`u zev#Z(5itmOOYmnRRFK$nNSDtramlQ4iY3~GyznIK$HJJ}{#A`2eCKmQ`4!Ep`Q|l_AYcx2gG4CsU=RH}~w< zkbb3HJ$c@nC*Mnqwot(b^XC0a=J$T@rLJoekbL!R++&1%M`v3MaGt@*9)J==(1^rz zNGW+q1QW&;5ylrbWWpSfcI^k$kT%WP^JReMw!qKJADx3C$&d;%WYUI%eqkEC#l*jH!~ScR1Io2L^a_0dER+6dXq_&jo$joPjooyFN3MC;=W2}GSJy* zzSPq+`R$J80KGRZGetXT*^W0~<`(B+5^Bzyhy)?obaiLDX|JjXC}b-^yK3P20Gu_M zkr~x&W_*PvlnJ4>S-{TSNtg&OBN@v?X9}mDH<8E-ya!2Has!j7_Twmv{vSu~Y?D(0 zvI5*W7}8!iRyD%IKS*}xRpq;F2gjTEvE)3rIgeAZh|qR8|G4m@GNX`I*z>`F56)hl zbuN0Z71FJ4qB=r_yPK3ZosQ!{vSU9r+JyM$Crxvl9O>Js1%diZ`D6-wQk>7`f qmPxpXz0Y!7uDKVaahxXJcv+w+O832xTaU{op5p#xxMU7FWWN9wtNhmh literal 0 HcmV?d00001 diff --git a/pageObjects/__pycache__/HomePage.cpython-310.pyc b/pageObjects/__pycache__/HomePage.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9f123b601ed03f51381abad8c76272a097101fd0 GIT binary patch literal 829 zcmY*X&2G~`5T0HC#6&KLo;YyeMCBgx00>Y;R45WkA`AkVpq1m@5T{-{tev7%;nbdx z;2GeA`bxfX;uSbCW0T5^G_yN9v$Nkfv&G(CA5h+W{W<%>0Dh6v6$_ms)bbFG1j#bc zEMkoIJmcDmEC$a&TGGA*XQ(Gu@Pc(rAg0}33zRnDw`V@bFRR6xcqrKd@y}oDpOA1#wO0I zbUN82i`eLiDV8d!%IRuTEsFe~J6$21@vM#P;0;!r+7lwp(@F@cS`wT-JHLIMv5O`+ zf@}E?_&q${!V;FO;!Eore7Ao9gUX?^3-+09SqR3#q`++m)c!oprBIpDDzA)<5u}IR zshuQClT$;34Y=vy68TAIIt}sG+@M&Hnh`KL? zF626+y)VSab)2;kL(K3?grNwJUmOo#jb9onZfH8@CK+l|#}JT)1Mw&+=s}-*+_#(4 zQQ*{fads+C*Lv_t&Dx0$l0xeuAIvuGi+4KH88jcVXg_4rjHXiO%?3i-frl-R$26U$ K13vg{pZ^7bfgc5ZzrniIb)XN>5M;i3`dl2aX6;RYHV-DvCr=E6dW#@lI5y{$h7cVpLA) zzu=M_;V12tQ~v@Nm`wsi0>+y0?0P)&-t#)&-)|ALr%%3)KT|@!*~PB8xHv&quQ3QB zXhM8@X9-Q2v#7SM>UFU96OY44v5+GA=*%Y-EeMv-JG;WA!EZBnjEkWOsj(3aw z$go2V>s1){&td#R#veeQhq1S7Jw)XGf9iD84jd00qLkVU}r35Nty$TUy#C`4M) zjyKKISHm~_Y;bYbag3`VnHX2YT${$W{0otHvGDt#|15Ziq*ZVc$`B_6qbj-#Wjd1i z6m?QTQR&M(+b)9=F`#Img5QL@MP&|9;CND<#@W?qi_LOSmV2Atq27;=M}J=UyLgBa zdYorr3Y?o3=V>m=#O7_z-WAVnrGc{wGr*nKT1?t6uH#h8J?ca_jvICDrtvHOWe3=D6h<3sbCV% ib%~m+0qwxH@=J@|c+WR%kMTz#s*M2&P^ zs;Pe^?`%;Pw$Q-;#vZl339z9DFr+9LbQ-!{EY@IMSV?o|4m!}c#iQ+vh9TpBkI{>; S*hMGf+Nb`};QusYG5Z1Xa$X?- literal 0 HcmV?d00001 From 774a20d720f568a7e1f12533e6aa6536c02a15ff Mon Sep 17 00:00:00 2001 From: Xaranti <85513286+Xaranti@users.noreply.github.com> Date: Thu, 16 Jun 2022 22:41:47 +0200 Subject: [PATCH 16/20] Add files via upload --- Tests/pageObjects/CheckoutPage.py | 19 ++++++++++++++++++ Tests/pageObjects/ConfirmPage.py | 0 Tests/pageObjects/HomePage.py | 15 ++++++++++++++ .../__pycache__/CheckoutPage.cpython-310.pyc | Bin 0 -> 1129 bytes .../__pycache__/HomePage.cpython-310.pyc | Bin 0 -> 829 bytes Tests/utilities/BaseClass.py | 12 +++++++++++ .../__pycache__/BaseClass.cpython-310.pyc | Bin 0 -> 843 bytes .../__pycache__/BaseClass.cpython-39.pyc | Bin 0 -> 381 bytes 8 files changed, 46 insertions(+) create mode 100644 Tests/pageObjects/CheckoutPage.py create mode 100644 Tests/pageObjects/ConfirmPage.py create mode 100644 Tests/pageObjects/HomePage.py create mode 100644 Tests/pageObjects/__pycache__/CheckoutPage.cpython-310.pyc create mode 100644 Tests/pageObjects/__pycache__/HomePage.cpython-310.pyc create mode 100644 Tests/utilities/BaseClass.py create mode 100644 Tests/utilities/__pycache__/BaseClass.cpython-310.pyc create mode 100644 Tests/utilities/__pycache__/BaseClass.cpython-39.pyc diff --git a/Tests/pageObjects/CheckoutPage.py b/Tests/pageObjects/CheckoutPage.py new file mode 100644 index 0000000..22f5a08 --- /dev/null +++ b/Tests/pageObjects/CheckoutPage.py @@ -0,0 +1,19 @@ +from selenium.webdriver.common.by import By + +class CheckOutPage: + + cardTitle = (By.CSS_SELECTOR, ".card-title a") + cardFooter = (By.CSS_SELECTOR,".card-footer button") + checkout = (By.CSS_SELECTOR,"a[class*='btn-primary']") + + def __init__(self,driver): + self.driver=driver + + def getCardTitles(self): + return self.driver.find_elements(*CheckOutPage.cardTitle) + + def getCardFooter(self): + return self.driver.find_elements(*CheckOutPage.cardFooter) + + def Checkout(self): + return self.driver.find_element(*CheckOutPage.checkout) \ No newline at end of file diff --git a/Tests/pageObjects/ConfirmPage.py b/Tests/pageObjects/ConfirmPage.py new file mode 100644 index 0000000..e69de29 diff --git a/Tests/pageObjects/HomePage.py b/Tests/pageObjects/HomePage.py new file mode 100644 index 0000000..dd64980 --- /dev/null +++ b/Tests/pageObjects/HomePage.py @@ -0,0 +1,15 @@ +from selenium.webdriver.common.by import By +from pageObjects.CheckoutPage import CheckOutPage + +class HomePage: + + shop = (By.CSS_SELECTOR, "a[href*='shop']") + + def __init__(self,driver): + self.driver = driver + + + def shopItem(self): + self.driver.find_element(*HomePage.shop).click() + checkOutPage = CheckOutPage(self.driver) + return checkOutPage \ No newline at end of file diff --git a/Tests/pageObjects/__pycache__/CheckoutPage.cpython-310.pyc b/Tests/pageObjects/__pycache__/CheckoutPage.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..812fb8cbe9afe83abd9ac8b74c09878315358cea GIT binary patch literal 1129 zcma)4Pm9w)6rY)-ZJH*l?ka+a>}{#A`2eCKmQ`4!Ep`Q|l_AYcx2gG4CsU=RH}~w< zkbb3HJ$c@nC*Mnqwot(b^XC0a=J$T@rLJoekbL!R++&1%M`v3MaGt@*9)J==(1^rz zNGW+q1QW&;5ylrbWWpSfcI^k$kT%WP^JReMw!qKJADx3C$&d;%WYUI%eqkEC#l*jH!~ScR1Io2L^a_0dER+6dXq_&jo$joPjooyFN3MC;=W2}GSJy* zzSPq+`R$J80KGRZGetXT*^W0~<`(B+5^Bzyhy)?obaiLDX|JjXC}b-^yK3P20Gu_M zkr~x&W_*PvlnJ4>S-{TSNtg&OBN@v?X9}mDH<8E-ya!2Has!j7_Twmv{vSu~Y?D(0 zvI5*W7}8!iRyD%IKS*}xRpq;F2gjTEvE)3rIgeAZh|qR8|G4m@GNX`I*z>`F56)hl zbuN0Z71FJ4qB=r_yPK3ZosQ!{vSU9r+JyM$Crxvl9O>Js1%diZ`D6-wQk>7`f qmPxpXz0Y!7uDKVaahxXJcv+w+O832xTaU{op5p#xxMU7FWWN9wtNhmh literal 0 HcmV?d00001 diff --git a/Tests/pageObjects/__pycache__/HomePage.cpython-310.pyc b/Tests/pageObjects/__pycache__/HomePage.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9f123b601ed03f51381abad8c76272a097101fd0 GIT binary patch literal 829 zcmY*X&2G~`5T0HC#6&KLo;YyeMCBgx00>Y;R45WkA`AkVpq1m@5T{-{tev7%;nbdx z;2GeA`bxfX;uSbCW0T5^G_yN9v$Nkfv&G(CA5h+W{W<%>0Dh6v6$_ms)bbFG1j#bc zEMkoIJmcDmEC$a&TGGA*XQ(Gu@Pc(rAg0}33zRnDw`V@bFRR6xcqrKd@y}oDpOA1#wO0I zbUN82i`eLiDV8d!%IRuTEsFe~J6$21@vM#P;0;!r+7lwp(@F@cS`wT-JHLIMv5O`+ zf@}E?_&q${!V;FO;!Eore7Ao9gUX?^3-+09SqR3#q`++m)c!oprBIpDDzA)<5u}IR zshuQClT$;34Y=vy68TAIIt}sG+@M&Hnh`KL? zF626+y)VSab)2;kL(K3?grNwJUmOo#jb9onZfH8@CK+l|#}JT)1Mw&+=s}-*+_#(4 zQQ*{fads+C*Lv_t&Dx0$l0xeuAIvuGi+4KH88jcVXg_4rjHXiO%?3i-frl-R$26U$ K13vg{pZ^7bfgc5ZzrniIb)XN>5M;i3`dl2aX6;RYHV-DvCr=E6dW#@lI5y{$h7cVpLA) zzu=M_;V12tQ~v@Nm`wsi0>+y0?0P)&-t#)&-)|ALr%%3)KT|@!*~PB8xHv&quQ3QB zXhM8@X9-Q2v#7SM>UFU96OY44v5+GA=*%Y-EeMv-JG;WA!EZBnjEkWOsj(3aw z$go2V>s1){&td#R#veeQhq1S7Jw)XGf9iD84jd00qLkVU}r35Nty$TUy#C`4M) zjyKKISHm~_Y;bYbag3`VnHX2YT${$W{0otHvGDt#|15Ziq*ZVc$`B_6qbj-#Wjd1i z6m?QTQR&M(+b)9=F`#Img5QL@MP&|9;CND<#@W?qi_LOSmV2Atq27;=M}J=UyLgBa zdYorr3Y?o3=V>m=#O7_z-WAVnrGc{wGr*nKT1?t6uH#h8J?ca_jvICDrtvHOWe3=D6h<3sbCV% ib%~m+0qwxH@=J@|c+WR%kMTz#s*M2&P^ zs;Pe^?`%;Pw$Q-;#vZl339z9DFr+9LbQ-!{EY@IMSV?o|4m!}c#iQ+vh9TpBkI{>; S*hMGf+Nb`};QusYG5Z1Xa$X?- literal 0 HcmV?d00001 From 43c3ce921deacfc4cf97802dcad0afc408437bfe Mon Sep 17 00:00:00 2001 From: Xaranti <85513286+Xaranti@users.noreply.github.com> Date: Sun, 19 Jun 2022 22:08:11 +0200 Subject: [PATCH 17/20] visible text visible text --- locators | 3 +++ 1 file changed, 3 insertions(+) diff --git a/locators b/locators index ee1b767..ca409db 100644 --- a/locators +++ b/locators @@ -29,3 +29,6 @@ dropdown.select_by_index(0) pomoc w wyszukiwaniu elementów w konsoli: document.querySelectorAll('.nazwa-klasy') - daje mi wszystkie elementy które to spełniają document.querySelector('.nazwa-klasy') - daje mi 1 element na stronie jaki znajdzie + + +VISIBLE TEXT!!! From 35b06f39603da502304f7222941c4df2e8b9856c Mon Sep 17 00:00:00 2001 From: Xaranti <85513286+Xaranti@users.noreply.github.com> Date: Fri, 1 Jul 2022 14:43:18 +0200 Subject: [PATCH 18/20] Automatyzacja in progress --- Automatyzacja/Utilities/BaseClass.py | 26 ++ .../__pycache__/BaseClass.cpython-39.pyc | Bin 0 -> 1278 bytes .../conftest.cpython-39-pytest-7.1.2.pyc | Bin 0 -> 1185 bytes .../singleDiskBackup.cpython-39.pyc | Bin 0 -> 2507 bytes .../test_Main.cpython-39-pytest-7.1.2.pyc | Bin 0 -> 3566 bytes .../test_hdd.cpython-39-pytest-7.1.2.pyc | Bin 0 -> 12317 bytes .../test_logIn.cpython-39-pytest-7.1.2.pyc | Bin 0 -> 1455 bytes .../__pycache__/test_logIn.cpython-39.pyc | Bin 0 -> 1246 bytes ...ngleDiskBackup.cpython-39-pytest-7.1.2.pyc | Bin 0 -> 442 bytes .../test_singleDiskBackup.cpython-39.pyc | Bin 0 -> 2914 bytes .../test_storages.cpython-39-pytest-7.1.2.pyc | Bin 0 -> 9194 bytes Automatyzacja/conftest.py | 32 ++ Automatyzacja/logfile.log | 160 +++++++ .../__pycache__/devicesPage.cpython-39.pyc | Bin 0 -> 4396 bytes .../__pycache__/loginPage.cpython-39.pyc | Bin 0 -> 961 bytes .../__pycache__/planPage.cpython-39.pyc | Bin 0 -> 6157 bytes .../__pycache__/storagePage.cpython-39.pyc | Bin 0 -> 6459 bytes Automatyzacja/pageObjects/devicesPage.py | 64 +++ Automatyzacja/pageObjects/loginPage.py | 18 + Automatyzacja/pageObjects/planPage.py | 112 +++++ Automatyzacja/pageObjects/storagePage.py | 102 +++++ Automatyzacja/test.py | 3 + Automatyzacja/test_Main.py | 60 +++ Automatyzacja/test_hdd.py | 405 ++++++++++++++++++ Automatyzacja/test_storages.py | 224 ++++++++++ 25 files changed, 1206 insertions(+) create mode 100644 Automatyzacja/Utilities/BaseClass.py create mode 100644 Automatyzacja/Utilities/__pycache__/BaseClass.cpython-39.pyc create mode 100644 Automatyzacja/__pycache__/conftest.cpython-39-pytest-7.1.2.pyc create mode 100644 Automatyzacja/__pycache__/singleDiskBackup.cpython-39.pyc create mode 100644 Automatyzacja/__pycache__/test_Main.cpython-39-pytest-7.1.2.pyc create mode 100644 Automatyzacja/__pycache__/test_hdd.cpython-39-pytest-7.1.2.pyc create mode 100644 Automatyzacja/__pycache__/test_logIn.cpython-39-pytest-7.1.2.pyc create mode 100644 Automatyzacja/__pycache__/test_logIn.cpython-39.pyc create mode 100644 Automatyzacja/__pycache__/test_singleDiskBackup.cpython-39-pytest-7.1.2.pyc create mode 100644 Automatyzacja/__pycache__/test_singleDiskBackup.cpython-39.pyc create mode 100644 Automatyzacja/__pycache__/test_storages.cpython-39-pytest-7.1.2.pyc create mode 100644 Automatyzacja/conftest.py create mode 100644 Automatyzacja/logfile.log create mode 100644 Automatyzacja/pageObjects/__pycache__/devicesPage.cpython-39.pyc create mode 100644 Automatyzacja/pageObjects/__pycache__/loginPage.cpython-39.pyc create mode 100644 Automatyzacja/pageObjects/__pycache__/planPage.cpython-39.pyc create mode 100644 Automatyzacja/pageObjects/__pycache__/storagePage.cpython-39.pyc create mode 100644 Automatyzacja/pageObjects/devicesPage.py create mode 100644 Automatyzacja/pageObjects/loginPage.py create mode 100644 Automatyzacja/pageObjects/planPage.py create mode 100644 Automatyzacja/pageObjects/storagePage.py create mode 100644 Automatyzacja/test.py create mode 100644 Automatyzacja/test_Main.py create mode 100644 Automatyzacja/test_hdd.py create mode 100644 Automatyzacja/test_storages.py diff --git a/Automatyzacja/Utilities/BaseClass.py b/Automatyzacja/Utilities/BaseClass.py new file mode 100644 index 0000000..3fae572 --- /dev/null +++ b/Automatyzacja/Utilities/BaseClass.py @@ -0,0 +1,26 @@ +import pytest +import logging +import inspect +from selenium.webdriver.common.by import By +from selenium.webdriver.support.wait import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC + +@pytest.mark.usefixtures("setupBrowser") + +class BaseClass: + + def verifyLinkPresence(self,text): + element = WebDriverWait(self.driver, 10).until( + EC.presence_of_element_located((By.link,text))) + + def getLogger(self): + loggerName = inspect.stack()[1][3] + logger = logging.getLogger(loggerName) + fileHandler = logging.FileHandler('logfile.log') + formatter = logging.Formatter("[%(levelname)s] - %(asctime)s - %(name)s : %(message)s") + fileHandler.setFormatter(formatter) + + logger.addHandler(fileHandler) # filehandler object + + logger.setLevel(logging.DEBUG) + return logger \ No newline at end of file diff --git a/Automatyzacja/Utilities/__pycache__/BaseClass.cpython-39.pyc b/Automatyzacja/Utilities/__pycache__/BaseClass.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2a196e517cbd18e979845bef12e0205e63327d1b GIT binary patch literal 1278 zcmZ`&%We}f6tz8%OkP!Kg`iN03aL_OK~{)Gg-}VKiz=!>Ri&Y5n2w!j(s=~i(>77M zYCj}d@)7)qx2*CDY~XsPFNxxjug@J{-^cNF&}`NajBk5CPo#m+FReTrCMX*)g$IHn zieu!JEB0`q6OX`3Vk0p<6YD)Awi4U33v9-f#PO;aG1RY3>eQOzT|{kKxkj{dMXs>d zp!hR#of-H?9TzLo9)fHhv6C$xoiTnCL=t{1vWo!=C8K_rr8JUJmI~DnOy+|&&&~zo zq4w}_5KuN?ie(TC>3ktqOvyF!3~EplR+Cx~-B#6hAlPOc2odUIw*x3aHq1?!;x!0~ z#;A`ez9JJMjfp9(zCFfWGR0GT2}FQ1(wS*a-3r&Il}(E>l$ED4iWS-3R4)gd36_S; z&$>Q~S;A83$5|Lad0dBAW*nubuAxl9;;u3!yO64KWBCK|d9eBYc5D6kU?`6{>w&v| zaQrcsSrW+MCq>T%ZVMlox_I(qkIbuDIREKY-jx#H`}o0ZkIK!h^VYN3@o zE92-Y`8U5iBh4vNm)V$;i;;CyIz#`RJF(CK48XGeFx&~1u2a|sqSPPsFeV9 z&)sXafYMtd2X^*#KFZqKZXfQt7H>k*UQK&vyaQP(yTo2yS8;o=+P(E&+-xbHz)}7j zguZN{1;X>VR(_;L8hEsLe^GaNcU((3zOM`SeO2@QB%^t(al`k&=RrZ1@AC!lSGa!= zQU~EhT-^;0OrhVuV>%|+f83_B2Sdq()^@Vv{1^5XwiT&KbHt5RkX@KaUK1?xr^GKUr}QhTfl<-9M8|DYR4 O%z<#Q{u=rN3jYEHZB-)x literal 0 HcmV?d00001 diff --git a/Automatyzacja/__pycache__/conftest.cpython-39-pytest-7.1.2.pyc b/Automatyzacja/__pycache__/conftest.cpython-39-pytest-7.1.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..20f07491461dec213e066f762b82dd7c652a2fd3 GIT binary patch literal 1185 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 literal 0 HcmV?d00001 diff --git a/Automatyzacja/__pycache__/test_hdd.cpython-39-pytest-7.1.2.pyc b/Automatyzacja/__pycache__/test_hdd.cpython-39-pytest-7.1.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..11ad2eeae3d37ea7dd1df8c014d6782dc3e9c32e GIT binary patch literal 12317 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 gr+0hUOAoY<gP5=M^ literal 0 HcmV?d00001 diff --git a/Automatyzacja/__pycache__/test_logIn.cpython-39-pytest-7.1.2.pyc b/Automatyzacja/__pycache__/test_logIn.cpython-39-pytest-7.1.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d0f5c399dd70837419446288d832a46169b8f086 GIT binary patch literal 1455 zcmZuxOK;>v5O%kp<9X$=L;)eR3oOBhosfhe6cLo{W+nEp(Mrn!d4nv^bWh^MFLk$* z%xLC9IB?+)APzG}uAKP+{D!`AA$LxDqPm?#Ijk+0>+w~&>#KIh?Y3{g^=bFF{@Ya{Tl zVKv5KfMnx>_6bYQDFXvP9f5RTQ+A#VD5%TNPFRuA0}Xf?=kc+|xx7Y5r%oLpRqp2U z;O)Zm3?BX;h>0>(me&}gH zgZ~Nfg^4*w>@Uz3m6l_OD;?HE+P~u!W9pC&=}w#kf$oYWh%QfHJy+-_n5tz=?Wsi! zV0hthymBH$xwF2W7K1oFDY)3#{CazP`x*l$(oT!xBp)xtBunzW%c7*L=nabOT2VP} zX0dpZ-|cIB7d_dMkU={<5fRP#M+PJkKX;UbwbrBd4S&H z-Q56m3=3;SJRVY2L3Z|aTS<{WXRKgyIT{uWxQ^&$nZouK5D7e{ zwy!i{LeO{2SqsdtslHmXvU%UwsExYLm-mgY{xH}hNPW9@uygckB#sz8W|W`CM<;|l zjR$8{d8FHf5535HmkRy#7`5%R0Yhuo`RLd47Nwb=`gtz74WAU i*TmivAL~B8$qG`X^jq~0@dXf{p_aZq)!{reT05H<@oYI*#Ocn zfic9eKoUn7JDCU~y~wL%Pxvy3f=c#9P1d7&B?lsmLcj*15j7qmR%7*Vh}FN6sL6s? zs1qK+y{Ln2W1kP0Nm(naT{@{h+$C!*@kAPEM{Y{4@jM^$(~L71RjbbuK?glDN_a)>Z8-ht1^d@nGy z-8%CQ$!9#l2O;y_NreecU>d9j7&0M%sh>D$vha``wB~ou?RMLry@|&fdqn?uioQVA zp-|2KcxlI&V!hWBc@m4AT$}aPTWf1;M=nd^Tn>%{D&e1y^}D$>ottb=;D% zxshf?X>P1UjZKH4E2}rhmwLTHX-uBI-7uqq-(A+_K&EE--T3P1&U%cy7Sf%C>XocF zn+RBErjyMmRz6=cE zHg4jkch+$NoLmGcB<=rNV`kd#1g@2`SaM2jlTw+pQaHIy>4!2F(-YN#%axmpV?nrv zRW1@$19k>TyT%G}=v6zNmJOl7d6t$^Rj+nsrgrD!>K;wzS$8m+*6P}6kZO9ndOFX_ xIkA`KH&8hp=x$QMQ~<|Otr)o!)j3eAU`~tMhIgjv-g8}}+rZjTLH9ut;a{@lJg5Kw literal 0 HcmV?d00001 diff --git a/Automatyzacja/__pycache__/test_singleDiskBackup.cpython-39-pytest-7.1.2.pyc b/Automatyzacja/__pycache__/test_singleDiskBackup.cpython-39-pytest-7.1.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..837394f22aec05a88d1c364d07351f33b0a45e84 GIT binary patch literal 442 zcmZutv1-FG5S1J!u@i^Rh0cXg@K8FHQbNeop%l6qgR!F{Q6t&zNp5iesL(Ic+NrmyB=|F%55K7%dz^C@?x7GU-vEht%a(Aes&#H5 z+e^Eh&sxa=f(h9S(P!u9;F2ro@)z<`2M zHX6GD-Nli{r)J`Hr8QM7S{!tetA8Y>sp|?Yy{d9c6J&kg6{6o|_*QE8U`XG3fS>Et zZTi&O6k&s4Uh;G+#4=y+nmX+pGqT($SV^-xMB}=3!JV!|qu`!X88afdY}TbZ0+o$8pk7Oek#%5vX+x*h||RBBg0kQKZ&XO{Ekk(Q3UjiMQD=X2wZu zxe|z;I3SK3lOuP2&0aa>%n44sHyax#-KbJG+2?tm^S);Gxid3m4W2)je(n4{t7(5B zGWi&Q+=Ex#1wb`Q0xcwMLU64IdT6u_wKf7XwAz+hn?a#n_(r1^Exgib;b*;Fq~^L- zFP?x6txnRZ1J?{08DEWsB)JqoGuaBa;qL2mTm8V#(%E9LUKBFqcuANk1()jvx8banPDTyBaCL-=G3vG)GL2AmjA0;1{=5@%#>v z4Ye2A5uxN5%A(e~G+vlgKh}?|V~uFCa8#rQatCyRZ^F7XuYuImvBrOy;8-KhOEM%! zXst{OBWq*1GA&NfN*j>F4ed8QG70Q?#*@;7oTlte(f4>7^Wrxg6R%Ikd|;w0FVZOPI%(#?Uy;R&^w&a(})u?~S{|ZiMynlv!j6&GN39cV*1>h#{&dreBkB5)Sd#2eF4aG;J%JM@YW3|CZ0^Av%4DqN z+6__L9?YMo*v%&V53Y53QpVAy%YC;IxE&TO*D?|)UCm*x2C-nkTg-K1h0;Yl?BGdz zwxf;l?|`UyuD6*ctL(wk|gM(v87zkHoC5y2tjT8 zqurHZV0U8Lx7{RZ@Hm!g5yJj9_4gHmm1L1beDl_}?Fyf=&D*d54TadzZo`YiB#ux_ zktuEPUci(M)Vs5-)Ikfe?8oljxxm+@8=?-8jN``?e5^{p=>@J3%eBdTKvVSNo`j13 z^!D+9gKvl@tJiB`Weu2>@7DI9c0uwPXPA80Qu7emf66D|nKV=tG ze51=EW$T}}kNeGa6wr4RYq=BiP?aw$rj0dlJul|ek0XV#Lug_FSOb1pfZc*kgfAvH zghuKHeTAbkcR{nU%i~@$k{k7v^h2gh;--xqp9OR*a%$C&lAdgvx8NBp$RStF9(9XP!CvhmUSUt;gLWB@>YBPrQgYZX z3h8pWBGrVFfob%uq$U!WF)DzG766S@NR^a{POg%9av9dMFo#t2Dp`OR{`5I=8CQDM zM1I*&YtTTgDw#tFe1+@T{4(04Rkv``iQrCkoV4sXVT>IF>x$$2&~t-~!_gUj9RUth z699eY_$|Q+N#I0RA|*>v>ZP;&h+dM! tTsAoiTnWReqejx0bKH(s5ugVXUMVNDbbggZbQiy60;jVIq_aXw`hTsDEO-C_ literal 0 HcmV?d00001 diff --git a/Automatyzacja/__pycache__/test_storages.cpython-39-pytest-7.1.2.pyc b/Automatyzacja/__pycache__/test_storages.cpython-39-pytest-7.1.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4887ecfaea34a4dd5fe76b1158ae2d8bb0231731 GIT binary patch literal 9194 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 literal 0 HcmV?d00001 diff --git a/Automatyzacja/conftest.py b/Automatyzacja/conftest.py new file mode 100644 index 0000000..3f14923 --- /dev/null +++ b/Automatyzacja/conftest.py @@ -0,0 +1,32 @@ +#regionImport +import pytest +from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.support.wait import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +#endregion + +def pytest_addoption(parser): + parser.addoption( + "--browser_name", action="store", default="chrome", help="help text here" + ) + +@pytest.fixture(scope="class") +def setupBrowser(request): + browser_name = request.config.getoption("browser_name") + if browser_name == "chrome": + driver = webdriver.Chrome(executable_path="D:\\chromedriver.exe") + + elif browser_name == "firefox": + pass + #firefox invocation + + else: + pass + #IE invo + + driver.get("https://3be5838c-0e80-4f15-9003-3a1d5b749330.testing.xopero.com") + driver.maximize_window() + request.cls.driver = driver + yield + driver.close() \ No newline at end of file diff --git a/Automatyzacja/logfile.log b/Automatyzacja/logfile.log new file mode 100644 index 0000000..7c15dd3 --- /dev/null +++ b/Automatyzacja/logfile.log @@ -0,0 +1,160 @@ +[INFO] - 2022-06-30 15:07:13,419 - test_restoreBMR : BMR restore stared +[INFO] - 2022-06-30 15:07:16,117 - test_restoreBMR : Main device set to restore +[INFO] - 2022-06-30 15:09:00,837 - test_restoreBMR : BMR restore stared +[INFO] - 2022-06-30 15:09:03,851 - test_restoreBMR : Main device set to restore +[INFO] - 2022-06-30 15:14:12,644 - test_restoreBMR : BMR restore stared +[INFO] - 2022-06-30 15:14:15,620 - test_restoreBMR : Main device set to restore +[INFO] - 2022-06-30 15:14:54,556 - test_restoreBMR : BMR restore stared +[INFO] - 2022-06-30 15:14:57,644 - test_restoreBMR : Main device set to restore +[INFO] - 2022-06-30 15:14:58,235 - test_restoreBMR : Restore Plan choosen +[INFO] - 2022-06-30 15:14:59,964 - test_restoreBMR : Restore type set as BMR +[INFO] - 2022-06-30 15:15:53,406 - test_restoreBMR : BMR restore stared +[INFO] - 2022-06-30 15:15:56,107 - test_restoreBMR : Main device set to restore +[INFO] - 2022-06-30 15:16:44,623 - test_restoreBMR : BMR restore started +[INFO] - 2022-06-30 15:16:47,285 - test_restoreBMR : Main device set to restore +[ERROR] - 2022-06-30 15:16:47,285 - test_restoreBMR : Plan list not found +[INFO] - 2022-06-30 15:22:42,074 - test_restoreBMR : BMR restore started +[INFO] - 2022-06-30 15:22:44,718 - test_restoreBMR : Main device set to restore +[ERROR] - 2022-06-30 15:22:44,718 - test_restoreBMR : Plan list not found +[INFO] - 2022-06-30 15:22:45,169 - test_restoreBMR : Restore Plan choosen +[INFO] - 2022-06-30 15:22:48,447 - test_restoreBMR : Restore type set as BMR +[INFO] - 2022-06-30 15:24:21,793 - test_restoreBMR : BMR restore started +[INFO] - 2022-06-30 15:24:24,611 - test_restoreBMR : Main device set to restore +[ERROR] - 2022-06-30 15:24:24,611 - test_restoreBMR : Plan list not found +[INFO] - 2022-06-30 15:24:25,021 - test_restoreBMR : Restore Plan choosen +[INFO] - 2022-06-30 15:24:27,643 - test_restoreBMR : Restore type set as BMR +[INFO] - 2022-06-30 15:25:39,030 - test_restoreBMR : BMR restore started +[INFO] - 2022-06-30 15:25:41,895 - test_restoreBMR : Main device set to restore +[ERROR] - 2022-06-30 15:25:41,895 - test_restoreBMR : Plan list not found +[INFO] - 2022-06-30 15:25:42,293 - test_restoreBMR : Restore Plan choosen +[INFO] - 2022-06-30 15:25:45,352 - test_restoreBMR : Restore type set as BMR +[INFO] - 2022-06-30 15:35:12,335 - test_restoreBMR : BMR restore started +[INFO] - 2022-06-30 15:35:15,427 - test_restoreBMR : Main device set to restore +[ERROR] - 2022-06-30 15:35:15,428 - test_restoreBMR : Plan list not found +[INFO] - 2022-06-30 15:35:15,820 - test_restoreBMR : Restore Plan choosen +[INFO] - 2022-06-30 15:35:17,683 - test_restoreBMR : Restore type set as BMR +[INFO] - 2022-06-30 15:36:27,421 - test_restoreBMR : BMR restore started +[INFO] - 2022-06-30 15:36:30,165 - test_restoreBMR : Main device set to restore +[ERROR] - 2022-06-30 15:36:30,165 - test_restoreBMR : Plan list not found +[INFO] - 2022-06-30 15:36:30,549 - test_restoreBMR : Restore Plan choosen +[INFO] - 2022-06-30 15:36:33,443 - test_restoreBMR : Restore type set as BMR +[INFO] - 2022-06-30 15:38:11,733 - test_restoreBMR : BMR restore started +[INFO] - 2022-06-30 15:38:14,657 - test_restoreBMR : Main device set to restore +[ERROR] - 2022-06-30 15:38:14,657 - test_restoreBMR : Plan list not found +[INFO] - 2022-06-30 15:38:15,323 - test_restoreBMR : Restore Plan choosen +[INFO] - 2022-06-30 15:38:17,714 - test_restoreBMR : Restore type set as BMR +[INFO] - 2022-06-30 15:38:48,269 - test_restoreBMR : BMR restore started +[INFO] - 2022-06-30 15:38:50,980 - test_restoreBMR : Main device set to restore +[ERROR] - 2022-06-30 15:38:50,980 - test_restoreBMR : Plan list not found +[INFO] - 2022-06-30 15:38:51,447 - test_restoreBMR : Restore Plan choosen +[INFO] - 2022-06-30 15:38:53,512 - test_restoreBMR : Restore type set as BMR +[INFO] - 2022-06-30 15:38:59,207 - test_restoreBMR : Directory to restore set +[INFO] - 2022-06-30 15:40:31,640 - test_restoreBMR : BMR restore started +[INFO] - 2022-06-30 15:40:34,658 - test_restoreBMR : Main device set to restore +[ERROR] - 2022-06-30 15:40:34,658 - test_restoreBMR : Plan list not found +[INFO] - 2022-06-30 15:40:35,214 - test_restoreBMR : Restore Plan choosen +[INFO] - 2022-06-30 15:40:37,831 - test_restoreBMR : Restore type set as BMR +[INFO] - 2022-06-30 15:40:43,588 - test_restoreBMR : Directory to restore set +[INFO] - 2022-06-30 15:41:21,980 - test_restoreBMR : BMR restore started +[INFO] - 2022-06-30 15:41:25,210 - test_restoreBMR : Main device set to restore +[ERROR] - 2022-06-30 15:41:25,210 - test_restoreBMR : Plan list not found +[INFO] - 2022-06-30 15:41:25,614 - test_restoreBMR : Restore Plan choosen +[INFO] - 2022-06-30 15:41:27,311 - test_restoreBMR : Restore type set as BMR +[INFO] - 2022-06-30 15:41:33,063 - test_restoreBMR : Directory to restore set +[INFO] - 2022-06-30 15:42:01,413 - test_restoreBMR : BMR restore started +[INFO] - 2022-06-30 15:42:04,304 - test_restoreBMR : Main device set to restore +[ERROR] - 2022-06-30 15:42:04,304 - test_restoreBMR : Plan list not found +[INFO] - 2022-06-30 15:42:04,730 - test_restoreBMR : Restore Plan choosen +[INFO] - 2022-06-30 15:42:07,675 - test_restoreBMR : Restore type set as BMR +[INFO] - 2022-07-01 10:22:18,177 - test_login : User sucessfully logged +[INFO] - 2022-07-01 10:22:24,789 - test_Add_Device : There are no devices to activate +[INFO] - 2022-07-01 10:26:04,239 - test_login : User sucessfully logged +[INFO] - 2022-07-01 10:26:14,594 - test_Add_Device : There are no devices to activate +[INFO] - 2022-07-01 10:26:28,144 - test_addPlan : Plan name set as 'Backup HDD' +[INFO] - 2022-07-01 10:26:28,737 - test_addPlan : Main device choosen +[ERROR] - 2022-07-01 10:26:34,217 - test_addPlan : Creating plan Failed +[INFO] - 2022-07-01 10:27:26,395 - test_login : User sucessfully logged +[INFO] - 2022-07-01 10:27:32,627 - test_Add_Device : There are no devices to activate +[INFO] - 2022-07-01 10:27:46,490 - test_addPlan : Plan name set as 'Backup HDD' +[INFO] - 2022-07-01 10:27:47,155 - test_addPlan : Main device choosen +[INFO] - 2022-07-01 10:27:48,103 - test_addPlan : Disk 'G:' set for backup +[INFO] - 2022-07-01 10:27:50,425 - test_addPlan : Storage for HDD backup set as Xopero Storage +[INFO] - 2022-07-01 10:27:51,056 - test_addPlan : Schedule set for 11:11 +[INFO] - 2022-07-01 10:27:52,118 - test_addPlan : Plan 'Backup HDD' started succesfully +[INFO] - 2022-07-01 10:27:57,655 - test_systemDisk : Plan name set as 'System Disk Backup' +[INFO] - 2022-07-01 10:27:58,255 - test_systemDisk : Main device choosen +[INFO] - 2022-07-01 10:27:59,279 - test_systemDisk : Disk 'C:' set for backup +[INFO] - 2022-07-01 10:27:59,690 - test_systemDisk : Storage for HDD backup set as Xopero Storage +[INFO] - 2022-07-01 10:28:00,273 - test_systemDisk : Schedule set for 11:11 +[INFO] - 2022-07-01 10:28:03,340 - test_systemDisk : Plan 'System Disk Backup' started succesfully +[INFO] - 2022-07-01 10:28:08,813 - test_Xopero_Disk_Variable : Plan name set as 'Xopero Var Backup' +[INFO] - 2022-07-01 10:28:09,325 - test_Xopero_Disk_Variable : Main device choosen +[INFO] - 2022-07-01 10:28:12,805 - test_Xopero_Disk_Variable : Storage for HDD backup set as Xopero Storage +[INFO] - 2022-07-01 10:28:13,321 - test_Xopero_Disk_Variable : Schedule set for 11:11 +[INFO] - 2022-07-01 10:28:16,390 - test_Xopero_Disk_Variable : Plan 'System Disk Backup' started succesfully +[INFO] - 2022-07-01 10:28:19,060 - test_prePlan : Predefined plan was successfuly added to device +[WARNING] - 2022-07-01 10:28:21,415 - test_prePlan : Plan 'System Disk Backup' already exist +[INFO] - 2022-07-01 10:28:21,736 - test_prePlan : Plan 'Endpoint&Server Total Protection' started as Full backup +[INFO] - 2022-07-01 10:28:33,138 - test_restore_file_image : Restore Plan choosen +[INFO] - 2022-07-01 10:28:35,952 - test_restore_file_image : Restore set as RAW +[INFO] - 2022-07-01 10:28:37,436 - test_restore_file_image : Folder already exist, starting restore +[INFO] - 2022-07-01 10:28:38,854 - test_restore_file_image : Restore started successfuly +[INFO] - 2022-07-01 10:28:41,276 - test_restore_file_image : Restore Plan choosen +[INFO] - 2022-07-01 10:28:41,276 - test_restore_file_image : Restore Plan choosen +[INFO] - 2022-07-01 10:28:43,395 - test_restore_file_image : Restore set as VHD +[INFO] - 2022-07-01 10:28:43,395 - test_restore_file_image : Restore set as VHD +[INFO] - 2022-07-01 10:28:44,733 - test_restore_file_image : Folder already exist, starting restore +[INFO] - 2022-07-01 10:28:44,733 - test_restore_file_image : Folder already exist, starting restore +[INFO] - 2022-07-01 10:28:46,087 - test_restore_file_image : Restore started successfuly +[INFO] - 2022-07-01 10:28:46,087 - test_restore_file_image : Restore started successfuly +[INFO] - 2022-07-01 10:28:48,397 - test_restore_file_image : Restore Plan choosen +[INFO] - 2022-07-01 10:28:48,397 - test_restore_file_image : Restore Plan choosen +[INFO] - 2022-07-01 10:28:48,397 - test_restore_file_image : Restore Plan choosen +[INFO] - 2022-07-01 10:28:50,504 - test_restore_file_image : Restore set as VHDX +[INFO] - 2022-07-01 10:28:50,504 - test_restore_file_image : Restore set as VHDX +[INFO] - 2022-07-01 10:28:50,504 - test_restore_file_image : Restore set as VHDX +[INFO] - 2022-07-01 10:28:52,199 - test_restore_file_image : Folder already exist, starting restore +[INFO] - 2022-07-01 10:28:52,199 - test_restore_file_image : Folder already exist, starting restore +[INFO] - 2022-07-01 10:28:52,199 - test_restore_file_image : Folder already exist, starting restore +[INFO] - 2022-07-01 10:28:53,605 - test_restore_file_image : Restore started successfuly +[INFO] - 2022-07-01 10:28:53,605 - test_restore_file_image : Restore started successfuly +[INFO] - 2022-07-01 10:28:53,605 - test_restore_file_image : Restore started successfuly +[INFO] - 2022-07-01 10:28:56,163 - test_restore_file_image : Restore Plan choosen +[INFO] - 2022-07-01 10:28:56,163 - test_restore_file_image : Restore Plan choosen +[INFO] - 2022-07-01 10:28:56,163 - test_restore_file_image : Restore Plan choosen +[INFO] - 2022-07-01 10:28:56,163 - test_restore_file_image : Restore Plan choosen +[INFO] - 2022-07-01 10:28:58,480 - test_restore_file_image : Restore set as VMDK +[INFO] - 2022-07-01 10:28:58,480 - test_restore_file_image : Restore set as VMDK +[INFO] - 2022-07-01 10:28:58,480 - test_restore_file_image : Restore set as VMDK +[INFO] - 2022-07-01 10:28:58,480 - test_restore_file_image : Restore set as VMDK +[INFO] - 2022-07-01 10:28:59,812 - test_restore_file_image : Folder already exist, starting restore +[INFO] - 2022-07-01 10:28:59,812 - test_restore_file_image : Folder already exist, starting restore +[INFO] - 2022-07-01 10:28:59,812 - test_restore_file_image : Folder already exist, starting restore +[INFO] - 2022-07-01 10:28:59,812 - test_restore_file_image : Folder already exist, starting restore +[INFO] - 2022-07-01 10:29:01,181 - test_restore_file_image : Restore started successfuly +[INFO] - 2022-07-01 10:29:01,181 - test_restore_file_image : Restore started successfuly +[INFO] - 2022-07-01 10:29:01,181 - test_restore_file_image : Restore started successfuly +[INFO] - 2022-07-01 10:29:01,181 - test_restore_file_image : Restore started successfuly +[INFO] - 2022-07-01 10:29:01,208 - test_restoreBMR : BMR restore started +[INFO] - 2022-07-01 10:29:17,956 - test_add_SMB_Storage : Name for SMB storage set as 'SMB' +[INFO] - 2022-07-01 10:29:18,367 - test_add_SMB_Storage : Creating password for SMB +[INFO] - 2022-07-01 10:29:23,141 - test_add_SMB_Storage : Password for SMB storage set +[CRITICAL] - 2022-07-01 10:29:31,322 - test_add_SMB_Storage : SMB storage creation failed +[INFO] - 2022-07-01 10:29:35,639 - test_add_NFS_Storage : Name for NFS storage set as 'NFS' +[INFO] - 2022-07-01 10:29:39,058 - test_add_NFS_Storage : NFS storage created +[INFO] - 2022-07-01 10:29:43,380 - test_add_S3_Storage : Name for S3 storage set as 'Minio S3' +[INFO] - 2022-07-01 10:29:43,725 - test_add_S3_Storage : Creating password for MinioS3 +[INFO] - 2022-07-01 10:29:48,371 - test_add_S3_Storage : Password for MinioS3 storage set +[INFO] - 2022-07-01 10:29:51,763 - test_add_S3_Storage : S3 storage created +[INFO] - 2022-07-01 10:30:00,989 - test_xoperoStorage : Xopero storage is avaiable +[INFO] - 2022-07-01 13:49:18,293 - test_add_SMB_Storage : Name for SMB storage set as 'SMB' +[INFO] - 2022-07-01 13:49:18,696 - test_add_SMB_Storage : Creating password for SMB +[INFO] - 2022-07-01 13:49:23,392 - test_add_SMB_Storage : Password for SMB storage set +[CRITICAL] - 2022-07-01 13:49:31,967 - test_add_SMB_Storage : SMB storage creation failed +[INFO] - 2022-07-01 13:49:36,432 - test_add_NFS_Storage : Name for NFS storage set as 'NFS' +[INFO] - 2022-07-01 13:49:40,282 - test_add_NFS_Storage : NFS storage created +[INFO] - 2022-07-01 13:49:44,670 - test_add_S3_Storage : Name for S3 storage set as 'Minio S3' +[INFO] - 2022-07-01 13:49:45,101 - test_add_S3_Storage : Creating password for MinioS3 +[INFO] - 2022-07-01 13:49:49,824 - test_add_S3_Storage : Password for MinioS3 storage set +[INFO] - 2022-07-01 13:49:53,755 - test_add_S3_Storage : S3 storage created +[INFO] - 2022-07-01 13:50:02,992 - test_xoperoStorage : Xopero storage is avaiable diff --git a/Automatyzacja/pageObjects/__pycache__/devicesPage.cpython-39.pyc b/Automatyzacja/pageObjects/__pycache__/devicesPage.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e68758b7cfd978a788bb6f4b284331756c0391ee GIT binary patch literal 4396 zcmcgvTT|Oc6qbAeV*`e84Oat6z$v!d(&;prOdAN3mYG1A(1#9}(X4eAM<7e?N`}~z zx8}LOq3v6KME^m5fnWR7ztE?ivyxy#Egn)&WOUBA-cQ!IXD{c#hK8~lUh8lFs4fg@ z+F#UAuOv2};_WS<0S$CptLullu6?UP0+MevNdBBSOhD>DE2jTOj#kt=iLI7NP`wh^ zc#5|-qH7x04t3BD6FhmA0{t{`n3gDks86CKqJD`|h%yqT5e-PxhbSviKcbvO8AO8; z4ImnlD2r%Vq8y^UM1zP%BpO0AD$y{aJCKKwx7y(tjKUrC<1hx}=qF$TCecsA6ilO^ zg1az-ei~+B4*gx2hXwRAum}b8v#nk+llDee(k?!Ny_IsA{!a0oTvVz} z-*+AQ<@T+jz`Bsa=+)fuE7+ErJPWw&U=lgClIhkPu0tF-H14@gVe(Ryndi-hM-R$} zH%=-@_PC9MZ2$Su-yMyoD%?wt3sfybiV-2z;kS`k^}Cw`k%RgCL{fubw(oTfzjg5J zV5i_SQR6;MQumpB$vxi{yufUmNXuP+>eRA%!K&j@B2MdrgLj0wX}B?S2h3+B-z|wi zQxuJ(FHXW`)BgQqzZzFfG;^;2B1Ms>6-nK7=9kP@+&r(kuiI-~LwFz;UI8qD>(3P} z3gl9ECQg}OaNJ9xeE32=Lg}}}+ToY)#W~zNv=&M@(i`hDoDu3#$4(D{<(-%0+9YSMuoU4-d=hPOuv<&FMEGcaEqXz%nr%m{rTtP3uR ziB1Z)^r=WA=ba|{(f#w)_T%IImVYdG4RxQfDG~e+v4>iR*#)y~R<${W$%~hpq5c<^=PxNL)wLM)_fT9e+~+Tt=f^9{ zh2bOCJw@E45<-R2LwzHmK7)CN<(bxP;X}#}Wx!QMp&GuZzlZX&p}bAoj*nh83=NVV zD$>*)e9h>gxB*JyJCwuYwGBLvI3-2exH7L-gdQr(hhYm+B!_r?`7kmO^HW9TjH2=e zt%q7Or??}xG3CXJ#2|`*v!Td)KZqfrhr;rh1~H{=NA*R#zI+h9E9RGqN;QZ#Xg$=L z@ufA6oS;MHi(6k8;8pcmeW(PfjN}Nvm$NkM8 zz7sjbB2Q+N%orJ}nZy*CyJV;W5c6af$xs#(D`f7Ip;K85kQpX3Lgo&caWYgy394_z z44FAHl&nR8%rY5DJmLYFH8R(gh(uH?$-;#yEAKIyOd_ktev+A6KJs_=ipkC#Z867c n*2|Z?8q}X<{O7aoI^}9hhDTDnY3XF11X2B(ibYv-3?}{sO%56~ literal 0 HcmV?d00001 diff --git a/Automatyzacja/pageObjects/__pycache__/loginPage.cpython-39.pyc b/Automatyzacja/pageObjects/__pycache__/loginPage.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..18c1367477656c9925583479fcc569f9d582f711 GIT binary patch literal 961 zcmZuvPfyf96rY*4yWO$`Lp*Ts;0bID3us~tK>~;h1{Mq?>awKic80Y}|1mQaw-OU0 zXFmfRJ^2m%AanJ^SMcPUHYFCI)_YHJ2%H7#4m2vka*1^ad=DqFWNw zTwB>t*`60Bq4YeRP?U6VG5N2Y)@V7vus$-4wHzhW4FD2dV2Uq6j59PK14Ehv>pQxD z_T7rr%b0O1W<#uTiL{JRr`f*JmlsoUOGsaY{_(?w$MY+n(v0!66{K--e`kAoJzP3z ze|Y=l>B8p+uV20iyuGbQ2k*1_{_;LQbsc5OFa{+=#8_5#Ni~ncgnBGuF-s)Z+_?!( zH3WnBF&heHXTA`pDW|Gg$+K2UrmP?egJT!-nm(nQT{&By*J^Jj;{Z#=5O(lg_$F~N zaoxjmPup$kW+#5kJWn~E7pF9jG;Vs{N$yA03fB@Sv%R|gqGCuk*ZD-5>fP?@{szAT zm^ZYW)b5&3i8QIQJY8K$$tDhva)@n|ao1G$;PJ2|%;VN6>s3!mcQ#IwR&QA5=VPO5 U{&&B!mn!bdS}LJ4HL*?p0yNa%A^-pY literal 0 HcmV?d00001 diff --git a/Automatyzacja/pageObjects/__pycache__/planPage.cpython-39.pyc b/Automatyzacja/pageObjects/__pycache__/planPage.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4fd1307ca0fdfb1dcf5673e29c35cf12b80cb909 GIT binary patch literal 6157 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") + self.driver.find_element(*LogInPage.submitButton).click() + return \ No newline at end of file diff --git a/Automatyzacja/pageObjects/planPage.py b/Automatyzacja/pageObjects/planPage.py new file mode 100644 index 0000000..0431301 --- /dev/null +++ b/Automatyzacja/pageObjects/planPage.py @@ -0,0 +1,112 @@ +from selenium.webdriver.common.by import By + + +class PlanPage: + + plans = (By.XPATH,"//*[contains(text(),'Plans')]") + addPlan = (By.XPATH,"//*[contains(text(),'Add plan')]") + planName = (By.NAME,"backupPlanName") + runPlan = (By.CSS_SELECTOR,"button[aria-label='button']") + runFull = (By.XPATH,"//div[@class='cdk-overlay-pane']/div/div/button[2]") + runIncremental = (By.XPATH,"//div[@class='cdk-overlay-pane']/div/div/button[3]") + closePlanDashboard = (By.CSS_SELECTOR,"button[aria-label='Close']") + howToProtect = (By.XPATH,"//*[contains(text(),'How to protect')]") + fileLevel = (By.XPATH,"//*[contains(text(),'File-level')]") + imageLevel = (By.XPATH,"//*[contains(text(),'Image-level')]") + whichDevices = (By.XPATH,"//*[contains(text(),'Which devices?')]") + mainDeviceCheckbox = (By.CLASS_NAME, "mat-checkbox") + applyButton = (By.XPATH,"//*[contains(text(),'Apply')]") + whatToProtect = (By.XPATH,"//*[contains(text(),'What to protect?')]") + deviceName = (By.XPATH,'/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-add-rule/div/div[3]/div[2]/div[2]/div/h3') + diskCheckbox = (By.CSS_SELECTOR,"label[class='mat-checkbox-layout']") + saveChoice = (By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside[3]/app-aside/ng-component/app-add-device-rule/div/div[3]/button/span[1]") + whereToStore = (By.XPATH,"//*[contains(text(),'Where to store?')]") + xoperoStorage = (By.XPATH,"//*[contains(text(),'Xopero Storage')]") + when = (By.XPATH,"//*[contains(text(),'When?')]") + startAt = (By.XPATH,'/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-add-schedule/form/div[3]/div/mat-accordion/mat-expansion-panel[1]/div/div/app-monthly/div/mat-radio-group/div/div[2]/app-time/mat-form-field/div/div[1]/div/input') + saveRun = (By.XPATH,"//*[contains(text(),'Save&Run')]") + next = (By.XPATH,"//*[contains(text(),'Next')]") + saveSchedule = (By.XPATH,"//button[@type='submit']") + + + def __init__(self,driver): + self.driver = driver + + def planPage(self): + return self.driver.find_element(*PlanPage.plans).click() + + def AddPlan(self): + return self.driver.find_element(*PlanPage.addPlan).click() + + def PlanName(self): + return self.driver.find_element(*PlanPage.planName) + + def RunPlan(self,planRow): + return planRow.find_element(*PlanPage.runPlan).click() + + def RunFull(self,planRow): + return planRow.find_element(*PlanPage.runFull).click() + + def RunIncremental(self,planRow): + return planRow.find_element(*PlanPage.runIncremental).click() + + def ClosePlanDashboard(self): + return self.driver.find_element(*PlanPage.closePlanDashboard).click() + + def HowToProtect(self): + return self.driver.find_element(*PlanPage.howToProtect).click() + + def FileLevel(self): + return self.driver.find_element(*PlanPage.fileLevel).click() + + def ImageLevel(self): + return self.driver.find_element(*PlanPage.imageLevel).click() + + def WhichDevices(self): + return self.driver.find_element(*PlanPage.whichDevices).click() + + def MainDeviceCheckbox(self,main): + return main.find_element(*PlanPage.mainDeviceCheckbox).click() + + def ApplyButton(self): + return self.driver.find_element(*PlanPage.applyButton).click() + + def WhatToProtect(self): + return self.driver.find_element(*PlanPage.whatToProtect).click() + + def DeviceName(self): + return self.driver.find_element(*PlanPage.deviceName).click() + + def DiskCheckBox(self,diskletter): + return diskletter.find_element(*PlanPage.diskCheckbox).click() + + def SaveChoice(self): + return self.driver.find_element(*PlanPage.saveChoice).click() + + def WhereToStore(self): + return self.driver.find_element(*PlanPage.whereToStore).click() + + def XoperoStorage(self): + return self.driver.find_element(*PlanPage.xoperoStorage).click() + + def When(self): + return self.driver.find_element(*PlanPage.when).click() + + def StartAt(self): + return self.driver.find_element(*PlanPage.startAt) + + def SaveRun(self): + return self.driver.find_element(*PlanPage.saveRun).click() + + def Next(self): + return self.driver.find_element(*PlanPage.next).click() + + def SaveSchedule(self): + return self.driver.find_element(*PlanPage.saveSchedule).click() + + + + + + + diff --git a/Automatyzacja/pageObjects/storagePage.py b/Automatyzacja/pageObjects/storagePage.py new file mode 100644 index 0000000..6587ff8 --- /dev/null +++ b/Automatyzacja/pageObjects/storagePage.py @@ -0,0 +1,102 @@ +from selenium.webdriver.common.by import By + + +class StoragePage: + + storagesPage = (By.XPATH,'/html/body/app-root/app-main/app-menu/section/nav[1]/a[6]') + addStorage = (By.XPATH,'/html/body/app-root/app-main/div/app-toolbar-container/app-toolbar/mat-toolbar/mat-toolbar-row/div[1]/ng-component/button/span[1]') + storageName = (By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/mat-form-field/div/div[1]/div[2]/input") + localPath = (By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/div[2]/form/app-local/mat-form-field/div/div[1]/div/input") + save = (By.XPATH,"//*[contains(text(),'Save')]") + storageType = (By.XPATH,'/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/div[2]/form/ng-select/div') + networkLocation = (By.XPATH,"//*[contains(text(),'Network location')]") + SMBuserName = (By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/div[2]/form/app-smb/app-controlled-input/mat-form-field/div/div[1]/div[1]/input") + selectPassword = (By.XPATH,"//*[contains(text(),'Select or add')]") + addPassword = (By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-passwords-list-container/app-passwords-list/div/div[3]/button") + passwordName = (By.NAME,"passwordName") + passwords = (By.CSS_SELECTOR,"input[type='password']") + smbPath = (By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/div[2]/form/app-smb/mat-form-field/div/div[1]/div/input") + nfsShare = (By.XPATH,"//*[contains(text(),'Network File Storage')]") + nfsPath = (By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/div[2]/form/app-nfs/app-controlled-input/mat-form-field/div/div[1]/div[1]/input") + s3 = (By.XPATH,"//*[contains(text(),'S3 storage')]") + s3Login = (By.XPATH,"//span[text()='Access key ID']/../../../input") + s3serviceUrl = (By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/div[2]/form/app-amazon/app-controlled-input[2]/mat-form-field/div/div[1]/div[1]/input") + s3BucketName = (By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/div[2]/form/app-amazon/app-controlled-input[3]/mat-form-field/div/div[1]/div[1]/input") + Backblaze = (By.XPATH,"//*[contains(text(),'Backblaze B2')]") + BackblazeBucket = (By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/div[2]/form/app-backblaze/app-controlled-input[2]/mat-form-field/div/div[1]/div[1]/input") + + def __init__(self,driver): + self.driver = driver + + def storagePage(self): + return self.driver.find_element(*StoragePage.storagesPage).click() + + def AddStorage(self): + return self.driver.find_element(*StoragePage.addStorage).click() + + def StorageName(self): + return self.driver.find_element(*StoragePage.storageName) + + def LocalPath(self): + return self.driver.find_element(*StoragePage.localPath) + + def Save(self): + return self.driver.find_element(*StoragePage.save).click() + + def StorageTypeSelect(self): + return self.driver.find_element(*StoragePage.storageType).click() + + def Type_SMB(self): + return self.driver.find_element(*StoragePage.networkLocation).click() + + def SMBusername(self): + return self.driver.find_element(*StoragePage.SMBuserName) + + def SelectPassword(self): + return self.driver.find_element(*StoragePage.selectPassword).click() + + def AddNewPassword(self): + return self.driver.find_element(*StoragePage.addPassword).click() + + def PasswordName(self): + return self.driver.find_element(*StoragePage.passwordName) + + def Passwords(self): + return self.driver.find_elements(*StoragePage.passwords) + + def SMBpath(self): + return self.driver.find_element(*StoragePage.smbPath) + + def Type_NFS(self): + return self.driver.find_element(*StoragePage.nfsShare).click() + + def NFSpath(self): + return self.driver.find_element(*StoragePage.nfsPath) + + def S3(self): + return self.driver.find_element(*StoragePage.s3).click() + + def LoginS3(self): + return self.driver.find_element(*StoragePage.s3Login) + + def S3Url(self): + return self.driver.find_element(*StoragePage.s3serviceUrl) + + def S3Bucket(self): + return self.driver.find_element(*StoragePage.s3BucketName) + + def BackBlaze(self): + return self.driver.find_element(*StoragePage.Backblaze).click() + + def BackBlazeBucket(self): + return self.driver.find_element(*StoragePage.BackblazeBucket) + + + + + + + + + + \ No newline at end of file diff --git a/Automatyzacja/test.py b/Automatyzacja/test.py new file mode 100644 index 0000000..a5a5698 --- /dev/null +++ b/Automatyzacja/test.py @@ -0,0 +1,3 @@ +import os +f = os.popen('ifconfig eth0 | grep "inet\ addr" | cut -d: -f2 | cut -d" " -f1') +your_ip=f.read() \ No newline at end of file diff --git a/Automatyzacja/test_Main.py b/Automatyzacja/test_Main.py new file mode 100644 index 0000000..836b284 --- /dev/null +++ b/Automatyzacja/test_Main.py @@ -0,0 +1,60 @@ +#regionImport +import pytest +from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.support.wait import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +from Utilities.BaseClass import BaseClass +from pageObjects.loginPage import LogInPage +from pageObjects.planPage import PlanPage +from pageObjects.storagePage import StoragePage +import time +#endregion + +class Test_Login(BaseClass): + + def test_login(self): + log = self.getLogger() + time.sleep(5) + logInPage = LogInPage(self.driver) + logInPage.logIn() + time.sleep(2) + try: + #assert self.driver.current_url == "http://localhost:28555/devices" + log.info("User sucessfully logged") + except: + log.critical("LogIn Failed") + raise + +class Test_AddDevice(BaseClass): + + def test_Add_Device(self): + log = self.getLogger() + self.driver.implicitly_wait(5) + + logInPage = LogInPage(self.driver) + logInPage.logIn() + try: + time.sleep(2) + if self.driver.find_element(By.ID,"mat-badge-content-0").is_displayed(): + self.driver.find_element(By.XPATH,'/html/body/app-root/app-main/div/app-toolbar-container/app-toolbar/mat-toolbar/mat-toolbar-row/div[2]/button[1]').click() + time.sleep(1) + self.driver.find_element(By.XPATH,'/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-activate-devices-table/div/div[3]/app-table/cdk-virtual-scroll-viewport/div[1]/table/tbody/tr/td[1]/mat-checkbox/label/span[1]').click() + self.driver.find_element(By.XPATH,'/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-activate-devices-table/div/div[4]/app-save-button/button/span[1]').click() + time.sleep(1) + self.driver.find_element(By.XPATH,'//app-license[2]/p').click() + self.driver.find_element(By.XPATH,'/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-licenses-list/div/div[4]/app-save-button/button/span[1]/span').click() + time.sleep(2) + assert self.driver.find_element(By.ID,"mat-badge-content-0").is_displayed()==False + log.error("Device was added successfully") + else: + log.info("There are no devices to activate") + except: + log.error("Device was not added") + raise + + + + + + diff --git a/Automatyzacja/test_hdd.py b/Automatyzacja/test_hdd.py new file mode 100644 index 0000000..49745ef --- /dev/null +++ b/Automatyzacja/test_hdd.py @@ -0,0 +1,405 @@ +#regionImport +import pytest +from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.support.wait import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +from Utilities.BaseClass import BaseClass +from pageObjects.loginPage import LogInPage +from pageObjects.planPage import PlanPage +from pageObjects.storagePage import StoragePage +from pageObjects.devicesPage import DevicePage +import time +import socket +from selenium.webdriver.support.relative_locator import locate_with +from selenium.common.exceptions import NoSuchElementException +from selenium.common.exceptions import StaleElementReferenceException +#endregion + +class Test_HDD(BaseClass): + + def test_addPlan(self): + + log = self.getLogger() + self.driver.implicitly_wait(5) + + logInPage = LogInPage(self.driver) + logInPage.logIn() + time.sleep(2) + #assert self.driver.current_url == "http://localhost:28555/devices" + + planPage = PlanPage(self.driver) + planPage.planPage() + time.sleep(2) + #assert self.driver.current_url == "http://localhost:28555/plans/backup" + + try: + + if self.driver.find_element(By.XPATH,"//*[text()='Backup HDD']").is_displayed(): + log.warning("Plan 'Backup HDD' already exist") + planRow = self.driver.find_element(By.XPATH,"//*[text()='Backup HDD']/../..") + planPage.RunPlan(planRow) + planPage.RunIncremental(planRow) + log.info("Plan 'Backup HDD' started as incremental backup") + planPage.ClosePlanDashboard() + + else: + pass + + except: + + planPage.AddPlan() + planPage.PlanName().clear() + planPage.PlanName().send_keys("Backup HDD") + log.info("Plan name set as 'Backup HDD' ") + planPage.HowToProtect() + planPage.ImageLevel() + planPage.WhichDevices() + main = self.driver.find_element(By.XPATH,"//span[text()='Main']/../../..") + planPage.MainDeviceCheckbox(main) + log.info("Main device choosen") + planPage.ApplyButton() + planPage.WhatToProtect() + planPage.DeviceName() + + try: + + diskLetter = self.driver.find_element(By.XPATH,"//*[contains(text(),'(G:)')]/../../../..") + planPage.DiskCheckBox(diskLetter) + log.info("Disk 'G:' set for backup") + planPage.SaveChoice() + planPage.ApplyButton() + planPage.WhereToStore() + time.sleep(1) + planPage.XoperoStorage() + time.sleep(1) + log.info("Storage for HDD backup set as Xopero Storage") + planPage.When() + planPage.StartAt().send_keys('1111') + planPage.Next() + planPage.SaveSchedule() + log.info("Schedule set for 11:11") + time.sleep(1) + planPage.SaveRun() + log.info("Plan 'Backup HDD' started succesfully") + + except: + + log.error("Creating plan Failed") + raise + + def test_systemDisk(self): + log = self.getLogger() + self.driver.implicitly_wait(5) + planPage = PlanPage(self.driver) + #planPage.planPage() + + try: + + if self.driver.find_element(By.XPATH,"//*[text()='System Disk Backup']").is_displayed(): + log.warning("Plan 'System Disk Backup' already exist") + planRow = self.driver.find_element(By.XPATH,"//*[text()='System Disk Backup']/../..") + planPage.RunPlan(planRow) + planPage.RunIncremental(planRow) + log.info("Plan 'System Disk Backup' started as incremental backup") + planPage.ClosePlanDashboard() + + else: + pass + + except: + + planPage.AddPlan() + planPage.PlanName().clear() + planPage.PlanName().send_keys("System Disk Backup") + log.info("Plan name set as 'System Disk Backup' ") + planPage.HowToProtect() + planPage.ImageLevel() + planPage.WhichDevices() + main = self.driver.find_element(By.XPATH,"//span[text()='Main']/../../..") + planPage.MainDeviceCheckbox(main) + log.info("Main device choosen") + planPage.ApplyButton() + planPage.WhatToProtect() + planPage.DeviceName() + + try: + + diskLetter = self.driver.find_element(By.XPATH,"//*[contains(text(),'(C:)')]/../../../..") + planPage.DiskCheckBox(diskLetter) + log.info("Disk 'C:' set for backup") + planPage.SaveChoice() + planPage.ApplyButton() + planPage.WhereToStore() + planPage.XoperoStorage() + log.info("Storage for HDD backup set as Xopero Storage") + planPage.When() + planPage.StartAt().send_keys('1111') + planPage.Next() + planPage.SaveSchedule() + log.info("Schedule set for 11:11") + time.sleep(2) + planPage.SaveRun() + time.sleep(1) + log.info("Plan 'System Disk Backup' started succesfully") + + except: + + log.error("Creating plan Failed") + raise + + def test_Xopero_Disk_Variable(self): + + log = self.getLogger() + self.driver.implicitly_wait(5) + planPage = PlanPage(self.driver) + #planPage.planPage() + + + try: + + if self.driver.find_element(By.XPATH,"//*[text()='Xopero Var Backup']").is_displayed(): + log.warning("Plan 'System Disk Backup' already exist") + planRow = self.driver.find_element(By.XPATH,"//*[text()='System Disk Backup']/../..") + planPage.RunPlan(planRow) + planPage.RunIncremental(planRow) + log.info("Plan 'Xopero Var Backup' started as incremental backup") + planPage.ClosePlanDashboard() + + else: + pass + except: + + planPage.AddPlan() + planPage.PlanName().clear() + planPage.PlanName().send_keys("Xopero Var Backup") + log.info("Plan name set as 'Xopero Var Backup' ") + planPage.HowToProtect() + planPage.ImageLevel() + planPage.WhichDevices() + main = self.driver.find_element(By.XPATH,"//span[text()='Main']/../../..") + planPage.MainDeviceCheckbox(main) + log.info("Main device choosen") + planPage.ApplyButton() + planPage.WhatToProtect() + planPage.DeviceName() + + try: + self.driver.find_element(By.CSS_SELECTOR,"div[class='item__content']").click() + self.driver.find_element(By.XPATH,"//*[contains(text(),'Set global rules')]").click() + self.driver.find_element(By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-add-rule/div/div[3]/div/div[2]/app-rule/div/app-paths/div/form/ng-select").click() + self.driver.find_element(By.XPATH, "//*[contains(text(),'SYSTEM_DISK')]").click() + planPage.ApplyButton() + planPage.WhereToStore() + time.sleep(1) + planPage.XoperoStorage() + time.sleep(1) + log.info("Storage for HDD backup set as Xopero Storage") + planPage.When() + planPage.StartAt().send_keys('1111') + planPage.Next() + planPage.SaveSchedule() + log.info("Schedule set for 11:11") + time.sleep(2) + planPage.SaveRun() + time.sleep(1) + + log.info("Plan 'System Disk Backup' started succesfully") + + except: + + log.error("Creating plan Failed") + raise + + def test_prePlan(self): + + log = self.getLogger() + self.driver.implicitly_wait(5) + devicePage = DevicePage(self.driver) + devicePage.devicePage() + planPage = PlanPage(self.driver) + + time.sleep(1) + devicePage.AssignPlan() + self.driver.find_element(By.XPATH,'//*[contains(text(),"Endpoint&Server Total Protection")]').click() + + time.sleep(1) + #assert self.driver.find_element(By.XPATH,"//*[text()='Endpoint&Server Total Protection']").is_displayed() + log.info("Predefined plan was successfuly added to device") + + planPage.planPage() + time.sleep(2) + try: + if self.driver.find_element(By.XPATH,"//*[text()='Endpoint&Server Total Protection']").is_displayed(): + log.warning("Plan 'System Disk Backup' already exist") + planRow = self.driver.find_element(By.XPATH,"//*[contains(text(),'Endpoint&Server Total Protection')]/../..") + planPage.RunPlan(planRow) + planPage.RunFull(planRow) + log.info("Plan 'Endpoint&Server Total Protection' started as Full backup") + planPage.ClosePlanDashboard() + except: + log.error("Error during runnin predefined plan") + raise + + def test_restoreISCSI(self): + log = self.getLogger() + self.driver.implicitly_wait(5) + + devicePage = DevicePage(self.driver) + devicePage.devicePage() + time.sleep(1) + devicePage.mainDeviceRestore() + time.sleep(1) + #devicePage.PlanList() + # + ignored_exceptions=(NoSuchElementException,StaleElementReferenceException,) + planlist = WebDriverWait(self.driver, 10,ignored_exceptions=ignored_exceptions)\ + .until(EC.presence_of_element_located((devicePage.availablePlans)),log.error("Plan list not found")) + + try: + self.driver.find_element(By.XPATH,"//*[contains(text(),'Backup HDD')]").click() + try: + devicePage.RestoreLast() + devicePage.as_ISCSI() + devicePage.RestoreAll() + + hostname = socket.gethostname() + #ip = socket.gethostbyname(hostname) + ip = '192.168.4.237' + + ethernet = self.driver.find_element(By.XPATH,"//h4[contains(text(),'Ethernet')]/..") + ipPanel = ethernet.find_element(By.CSS_SELECTOR,"p[class='ng-star-inserted']").text + assert ipPanel in ip + + self.driver.find_element(By.XPATH,"//*[contains(text(),'Run iSCSI')]").click() + log.info("Uruchomiono restore poprzez iSCSI") + + except: + log.error("Error during starting restore plan") + raise + except: + log.error("Did not find indicated plan to restore") + raise + + def test_restore_file_image(self,getData): + + log = self.getLogger() + self.driver.implicitly_wait(5) + + self.driver.refresh() + devicePage = DevicePage(self.driver) + devicePage.devicePage() + + devicePage.mainDeviceRestore() + #devicePage.PlanList() + # + ignored_exceptions=(NoSuchElementException,StaleElementReferenceException,) + planlist = WebDriverWait(self.driver, 10,ignored_exceptions=ignored_exceptions)\ + .until(EC.presence_of_element_located((devicePage.availablePlans)),log.error("Plan list not found")) + + planlist.click() + # + try: + self.driver.find_element(By.XPATH,"//*[contains(text(),'Backup HDD')]").click() + log.info("Restore Plan choosen") + try: + devicePage.RestoreLast() + devicePage.FileImage() + devicePage.FirstDisk() + devicePage.RestoreSelected() + + devicePage.ImageFormat() + formats = self.driver.find_elements(By.CSS_SELECTOR,"div[role='option']") + for format in formats: + if format.text == getData["type"]: + log.info("Restore set as %s" %(getData["type"])) + format.click() + break + + devicePage.SelectDirectory() + + self.driver.find_element(By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside[4]/app-aside/ng-component/app-browse-device-files/div/div[3]/app-files-browser/app-files/ul/li[2]/div/app-icon").click() + folderTree = self.driver.find_element(By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside[4]/app-aside/ng-component/app-browse-device-files/div/div[3]/app-files-browser/app-files/ul/li[2]") + mainTree = self.driver.find_elements(By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside[4]/app-aside/ng-component/app-browse-device-files/div/div[3]/app-files-browser/app-files/ul/li[2]/ul/li") + + #iteration through folders + avoidin stale element reference + for i in range(1,len(mainTree)): + ignored_exceptions=(NoSuchElementException,StaleElementReferenceException,) + element = WebDriverWait(self.driver, 5,ignored_exceptions=ignored_exceptions)\ + .until(EC.presence_of_element_located((By.XPATH, "/html/body/app-root/app-main/div/app-content/div[1]/aside[4]/app-aside/ng-component/app-browse-device-files/div/div[3]/app-files-browser/app-files/ul/li[2]/ul/li[%i]"%(i)))) + if element.text == 'Backup HDD': + log.info("Folder already exist, starting restore") + element.find_element(By.TAG_NAME,'mat-checkbox').click() + self.driver.find_element(By.XPATH,"//*[contains(text(),'Apply')]").click() + time.sleep(1) + devicePage.StartNow() + log.info("Restore started successfuly") + return + else: + pass + + + time.sleep(1) + log.info("Restore folder not found, creating new one") + x = self.driver.find_element(By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside[4]/app-aside/ng-component/app-browse-device-files/div/div[3]/app-files-browser/app-files/ul/li[2]/div") + x.find_element(By.CSS_SELECTOR,"svg[data-icon='folder-plus']").click() + folderTree.find_element(By.CSS_SELECTOR,"input[data-placeholder='New catalog name']").send_keys('Backup HDD') + folderTree.find_element(By.CSS_SELECTOR,"button[title='Add catalog']").click() + log.info("Restore folder created") + time.sleep(1) + self.driver.find_element(By.XPATH,"//*[contains(text(),'Apply')]").click() + time.sleep(1) + self.driver.find_element(By.XPATH,"//*[contains(text(),'Start now')]").click() + log.info("Restore started sucessfuly") + + except: + log.error('Error during lunching restore') + raise + except: + log.warning('Intended plan not found') + raise + + + @pytest.fixture(params= [{'type':'RAW','plan':'Backup HDD'},{'type':'VHD','plan':'Backup HDD'},{'type':'VHDX','plan':'Backup HDD'},{'type':'VMDK','plan':'Backup HDD'}]) + def getData(self, request): + return request.param + + def test_restoreBMR(self): + log = self.getLogger() + self.driver.implicitly_wait(5) + + logInPage = LogInPage(self.driver) + devicePage = DevicePage(self.driver) + planPage = PlanPage(self.driver) + log.info('BMR restore started') + logInPage.logIn() + time.sleep(1) + devicePage.devicePage() + + devicePage.mainDeviceRestore() + log.info("Main device set to restore") + ignored_exceptions=(NoSuchElementException,StaleElementReferenceException,) + planlist = WebDriverWait(self.driver, 10,ignored_exceptions=ignored_exceptions)\ + .until(EC.presence_of_element_located((devicePage.availablePlans)),log.error("Plan list not found")) + planlist.click() + + assert self.driver.find_element(By.XPATH,"//*[contains(text(),'Backup HDD')]").is_displayed() + self.driver.find_element(By.XPATH,"//*[contains(text(),'Backup HDD')]").click() + log.info("Restore Plan choosen") + devicePage.RestoreLast() + devicePage.BareMetalRestore() + log.info("Restore type set as BMR") + devicePage.FirstDisk() + devicePage.RestoreSelected() + devicePage.SelectDirectory() + BrowseDevices = self.driver.find_element(By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside[4]") + + diskLetter = BrowseDevices.find_element(By.XPATH,"//*[contains(text(),'(G:)')]/../../../..") + #time.sleep(1) + diskCheckbox = WebDriverWait(diskLetter,10)\ + .until(EC.element_to_be_clickable((By.CSS_SELECTOR,"label[class='mat-checkbox-layout']"))) + diskCheckbox.click() + #self.driver.execute_script("arguments[0].click();",diskLetter.find_element(By.CSS_SELECTOR,"label[class='mat-checkbox-layout']")) + time.sleep(5) + log.info("Directory to restore set") + \ No newline at end of file diff --git a/Automatyzacja/test_storages.py b/Automatyzacja/test_storages.py new file mode 100644 index 0000000..da2df7c --- /dev/null +++ b/Automatyzacja/test_storages.py @@ -0,0 +1,224 @@ +#regionImport +import pytest +from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.support.wait import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +from Utilities.BaseClass import BaseClass +from pageObjects.loginPage import LogInPage +from pageObjects.planPage import PlanPage +from pageObjects.storagePage import StoragePage +import time +#endregion + +class Test_Storages(BaseClass): + + def test_add_Local_Storage(self): + + self.driver.implicitly_wait(5) + log = self.getLogger() + logInPage = LogInPage(self.driver) + logInPage.logIn() + time.sleep(2) + assert self.driver.current_url == "https://3be5838c-0e80-4f15-9003-3a1d5b749330.testing.xopero.com/devices" + + storagePage = StoragePage(self.driver) + storagePage.storagePage() + storagePage.AddStorage() + storagePage.StorageName().clear() + storagePage.StorageName().send_keys('Lokal') + log.info("Name for local storage set as 'Lokal'") + storagePage.LocalPath().send_keys('D:\\storage beta') + storagePage.Save() + + self.driver.refresh() + time.sleep(2) + + try: + assert self.driver.find_element(By.XPATH,"//*[contains(text(),'Lokal')]").is_displayed() + log.info("Local storage created") + except: + log.critical("Local storage creation failed") + raise + + def test_add_SMB_Storage(self): + + self.driver.implicitly_wait(5) + log = self.getLogger() + + time.sleep(2) + storagePage = StoragePage(self.driver) + storagePage.storagePage() + storagePage.AddStorage() + time.sleep(2) + + storagePage.StorageName().clear() + storagePage.StorageName().send_keys('SMB') + log.info("Name for SMB storage set as 'SMB'") + storagePage.StorageTypeSelect() + storagePage.Type_SMB() + storagePage.SMBusername().send_keys('admin') + storagePage.SelectPassword() + + log.info("Creating password for SMB") + storagePage.AddNewPassword() + storagePage.PasswordName().send_keys("Admin") + passwords = storagePage.Passwords() + for password in passwords: + password.send_keys("Admin_123") + time.sleep(2) + self.driver.find_element(By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-passwords-form-container/app-passwords-form/form/div[3]/app-save-button/button/span[1]/span").click() + time.sleep(2) + log.info("Password for SMB storage set") + + + storagePage.SMBpath().send_keys(r"\\192.168.0.198\Public\MStasiak") + + storagePage.Save() + self.driver.refresh() + time.sleep(2) + try: + assert self.driver.find_element(By.XPATH,"//*[contains(text(),'Lokal')]").is_displayed() + log.info("SMB storage created") + except: + log.critical("SMB storage creation failed") + raise + + def test_add_NFS_Storage(self): + self.driver.implicitly_wait(5) + log = self.getLogger() + + time.sleep(2) + storagePage = StoragePage(self.driver) + storagePage.storagePage() + storagePage.AddStorage() + time.sleep(2) + + storagePage.StorageName().clear() + storagePage.StorageName().send_keys('NFS') + log.info("Name for NFS storage set as 'NFS'") + + storagePage.StorageTypeSelect() + storagePage.Type_NFS() + storagePage.NFSpath().send_keys("192.168.0.198:/StorageNFS/Marek") + storagePage.Save() + + self.driver.refresh() + time.sleep(2) + try: + assert self.driver.find_element(By.XPATH,"//*[contains(text(),'NFS')]").is_displayed() + log.info("NFS storage created") + except: + log.critical("NFS storage creation failed") + raise + + def test_add_S3_Storage(self): + self.driver.implicitly_wait(5) + log = self.getLogger() + + time.sleep(2) + storagePage = StoragePage(self.driver) + storagePage.storagePage() + storagePage.AddStorage() + time.sleep(2) + + storagePage.StorageName().clear() + storagePage.StorageName().send_keys('Minio S3') + log.info("Name for S3 storage set as 'Minio S3'") + + + storagePage.StorageTypeSelect() + storagePage.S3() + storagePage.LoginS3().send_keys("minioadmin") + storagePage.SelectPassword() + + log.info("Creating password for MinioS3") + storagePage.AddNewPassword() + storagePage.PasswordName().send_keys("minio") + passwords = storagePage.Passwords() + for password in passwords: + password.send_keys("minioadmin") + time.sleep(2) + self.driver.find_element(By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-passwords-form-container/app-passwords-form/form/div[3]/app-save-button/button/span[1]/span").click() + time.sleep(2) + log.info("Password for MinioS3 storage set") + + storagePage.S3Url().send_keys("http://192.168.4.237:9000") + storagePage.S3Bucket().send_keys("storage") + storagePage.Save() + + self.driver.refresh() + time.sleep(2) + try: + assert self.driver.find_element(By.XPATH,"//*[contains(text(),'Minio S3')]").is_displayed() + log.info("S3 storage created") + except: + log.critical("S3 storage creation failed") + raise + + def test_add_BackBlaze_storage(self): + self.driver.implicitly_wait(5) + log = self.getLogger() # + logInPage = LogInPage(self.driver) # + logInPage.logIn() + + time.sleep(2) + storagePage = StoragePage(self.driver) + storagePage.storagePage() + storagePage.AddStorage() + time.sleep(2) + + storagePage.StorageName().clear() + storagePage.StorageName().send_keys('BackBlaze') + log.info("Name for Blackblaze storage set as 'Backblaze'") + + storagePage.StorageTypeSelect() + storagePage.BackBlaze() + storagePage.LoginS3().send_keys("0032ff820db6e990000000006") + + storagePage.SelectPassword() + + log.info("Creating password for BackBlaze") + storagePage.AddNewPassword() + storagePage.PasswordName().send_keys("Backblaze") + passwords = storagePage.Passwords() + for password in passwords: + password.send_keys("K003XGuH9NSu9rTu/lSQ6kVcc8W1jEk") + time.sleep(2) + self.driver.find_element(By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-passwords-form-container/app-passwords-form/form/div[3]/app-save-button/button/span[1]/span").click() + time.sleep(2) + log.info("Password for BackBlaze storage set") + + dropdown = self.driver.find_element(By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/div[2]/form/app-backblaze/ng-select") + dropdown.click() + self.driver.find_element(By.XPATH,"/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-storage/div/div[2]/form/app-backblaze/ng-select/ng-dropdown-panel/div[2]/div[2]/div[4]/div").click() + log.info("Storage region set") + + storagePage.BackBlazeBucket().send_keys("Wuwuwu") + time.sleep(1) + storagePage.Save() + + self.driver.refresh() + time.sleep(2) + try: + assert self.driver.find_element(By.XPATH,"//*[contains(text(),'BackBlaze')]").is_displayed() + log.info("Backblaze storage created") + except: + log.critical("Backblaze storage creation failed") + raise + + def test_xoperoStorage(self): + storagePage = StoragePage(self.driver) + log = self.getLogger() + try: + + self.driver.implicitly_wait(5) + time.sleep(2) + storagePage.storagePage() + time.sleep(1) + assert self.driver.find_element(By.XPATH,"//*[contains(text(),'Xopero Storage #1')]").is_displayed() + log.info("Xopero storage is avaiable") + except: + log.critical("Xopero storage is not avaiable!") + raise + return \ No newline at end of file From b34abb08453597b2a8acb3490dbf2e9ca273ac22 Mon Sep 17 00:00:00 2001 From: Xaranti <85513286+Xaranti@users.noreply.github.com> Date: Fri, 1 Jul 2022 14:44:15 +0200 Subject: [PATCH 19/20] Update loginPage.py --- Automatyzacja/pageObjects/loginPage.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Automatyzacja/pageObjects/loginPage.py b/Automatyzacja/pageObjects/loginPage.py index ccf1122..36e987a 100644 --- a/Automatyzacja/pageObjects/loginPage.py +++ b/Automatyzacja/pageObjects/loginPage.py @@ -12,7 +12,7 @@ def __init__(self,driver): def logIn(self): time.sleep(1) - self.driver.find_element(*LogInPage.login).send_keys('m.stasiak+130@xopero.com') - self.driver.find_element(*LogInPage.password).send_keys("OM&DiTrw") + self.driver.find_element(*LogInPage.login).send_keys('login') + self.driver.find_element(*LogInPage.password).send_keys("password") self.driver.find_element(*LogInPage.submitButton).click() - return \ No newline at end of file + return From 7b4078c07342de97d3ba769f750537f13189a780 Mon Sep 17 00:00:00 2001 From: Xaranti <85513286+Xaranti@users.noreply.github.com> Date: Tue, 12 Jul 2022 08:56:41 +0200 Subject: [PATCH 20/20] Update test_Main.py --- Automatyzacja/test_Main.py | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/Automatyzacja/test_Main.py b/Automatyzacja/test_Main.py index 836b284..4fef23f 100644 --- a/Automatyzacja/test_Main.py +++ b/Automatyzacja/test_Main.py @@ -26,33 +26,6 @@ def test_login(self): log.critical("LogIn Failed") raise -class Test_AddDevice(BaseClass): - - def test_Add_Device(self): - log = self.getLogger() - self.driver.implicitly_wait(5) - - logInPage = LogInPage(self.driver) - logInPage.logIn() - try: - time.sleep(2) - if self.driver.find_element(By.ID,"mat-badge-content-0").is_displayed(): - self.driver.find_element(By.XPATH,'/html/body/app-root/app-main/div/app-toolbar-container/app-toolbar/mat-toolbar/mat-toolbar-row/div[2]/button[1]').click() - time.sleep(1) - self.driver.find_element(By.XPATH,'/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-activate-devices-table/div/div[3]/app-table/cdk-virtual-scroll-viewport/div[1]/table/tbody/tr/td[1]/mat-checkbox/label/span[1]').click() - self.driver.find_element(By.XPATH,'/html/body/app-root/app-main/div/app-content/div[1]/aside/app-aside/ng-component/app-activate-devices-table/div/div[4]/app-save-button/button/span[1]').click() - time.sleep(1) - self.driver.find_element(By.XPATH,'//app-license[2]/p').click() - self.driver.find_element(By.XPATH,'/html/body/app-root/app-main/div/app-content/div[1]/aside[2]/app-aside/ng-component/app-licenses-list/div/div[4]/app-save-button/button/span[1]/span').click() - time.sleep(2) - assert self.driver.find_element(By.ID,"mat-badge-content-0").is_displayed()==False - log.error("Device was added successfully") - else: - log.info("There are no devices to activate") - except: - log.error("Device was not added") - raise -