vendredi 18 décembre 2020

Python/Selenium - not sure how to solve for loop problem

Hi I'm learning python/selenium and practicing automating testcases using a Page Object Model.

I'm trying to automate this page on this demo website https://admin-demo.nopcommerce.com/Admin/Category/List

Admin email: admin@yourstore.com Admin password: admin

In my test case I've added a new category to the table that lists all of the Categories. To test my code is robust, I've decided to add the new category to the end of the table. Therefore you have to go to the last page to view the category that's been added.

here is my CategoriesPage.py file where i call out all the selectors and methods I want to implement on those selectors.

I've tidied it up so it only contains code relevant to the problem.

class Categories:
tblrows_css = "tbody>tr"
numOfPages_css = "#categories-grid_paginate > ul > li"

def __init__(self, driver):
    self.driver = driver

def getRows(self):
    num_of_rows = self.driver.find_elements_by_css_selector(self.tblrows_css)
    return num_of_rows

def getPages(self):
    num_of_pages = self.driver.find_elements_by_css_selector(self.numOfPages_css)
    return num_of_pages

def pageClick(self, page_num):
    #self.driver.find_element_by_css_selector("#categories-grid_paginate > ul > li:nth-child(" + str(page_num) + ")").click()
    self.driver.find_element_by_link_text(str(page_num)).click()

def checkList(self, exp_name):
    flag = False
    num_of_pages = self.getPages()
    for page in range(1, len(num_of_pages) - 1):  # don't include arrow buttons, loops through each page until Name is found in table
        num_of_rows = self.getRows()
        self.pageClick(page)
        for item in range(1, len(num_of_rows) + 1):
            act_name = self.driver.find_element_by_css_selector("#categories-grid > tbody > tr:nth-child(" + str(item) + ") > td:nth-child(2)").text
            print(act_name)
            if exp_name == act_name:
                flag = True
                print("it works")
                break

    return flag

So I have 1 small problem and 1 big problem.

The small problem is

def pageClick(self, page_num):
#self.driver.find_element_by_css_selector("#categories-grid_paginate > ul > li:nth-child(" + str(page_num) + ")").click()
self.driver.find_element_by_link_text(str(page_num)).click()

I can't get the line I've commented out to work. So I've had to find a work around and use linktext So '1' for page 1, '2' for page 2 etc. However if there was ever a link '1' anywhere else on the page, this method would no longer work.

the error i get using the css_selector is

E       selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable: element has zero size
E         (Session info: chrome=87.0.4280.88)

venv\lib\site-packages\selenium\webdriver\remote\errorhandler.py:242: ElementNotInteractableException

The bigger problem is the checkList() method. I've put some print statements to help me figure out what's happening.

I'm trying to loop through all the rows in the 2nd column and get the name of the category(act_name) and see if it matches the exp_name. Once is does it will break out the loop, flag = True and when i assert flag in my test, it will return True and pass. If it doesn't then it will go to page 2 and loop through the table again for all items on page 2 etc.

The problem is when i run this method, it prints out everything on page 1 twice.

Computers
Computers >> Desktops
Computers >> Notebooks
Computers >> Software
Electronics
Electronics >> Camera & photo
Electronics >> Cell phones
Electronics >> Others
Apparel
Apparel >> Shoes
Apparel >> Clothing
Apparel >> Accessories
Digital downloads
Books
Jewelry
Computers
Computers >> Desktops
Computers >> Notebooks
Computers >> Software
Electronics
Electronics >> Camera & photo
Electronics >> Cell phones
Electronics >> Others
Apparel
Apparel >> Shoes
Apparel >> Clothing
Apparel >> Accessories
Digital downloads
Books
Jewelry
FAILED

I think I've figured out the problem.

for item in range(1, len(num_of_rows) + 1):

by the time I reach the last item on page 1 (jewelry) the iterator has a value of 15.

We then leave the nested for loop because exp_name != act_name, and go to the outer loop where we click on the 2nd page. Once on the 2nd page, we go back into the nested loop, at this point it should start at 1,2,3 again and start working it's way down each row in the table on page 2.

Why is it printing out all the items in the table on page 1 again?

I can see when the test fails, I have definitely hit page 2

Can anyone figure out where I'm going wrong?

Aucun commentaire:

Enregistrer un commentaire