2

I have a function where order and searchValue are the required parameters and action and buttonName are optional. I am using this function after running the search. This function allows the user to do different things based on the parameters..for example, clicking on the checkbox(can be anywhere in the row), click open button(anywhere in the row) etc.

here is the tr looks like(after returning three results):

enter image description here

here are the td inside tr(td can be checkbox, button etc)

enter image description here

This is the piece of code I wrote which is working fine, but want to know if I can write it in a better way or maybe I don't have to define xpath path so many times.

Here user defines the order(First or Last (tr)) and the searchValue, it will search the td with that text and perform the action in the same tr(depending on the order).

def listView(self, order, searchValue, action=False, buttonName=False):
        if order = 'First':
            #self.find_element("//*[starts-with(@id,'table_')]/tbody/tr")
            self.find_element('//*[starts-with(@id,"table_")]/tbody/tr[1]/td[text()= "'+ searchValue +'"]')
            if action == "Link":
                self.click(10, "//*[starts-with(@id,'table_')]/tbody/tr[1]")
            elif action == "Checkbox":
                self.click(10, '//*[starts-with(@id,"table_")]/tbody/tr[1]/td/input[@type="checkbox"]')
            elif action == "Button" and buttonName:
                self.click(10, '//*[starts-with(@id,"table_")]/tbody/tr[1]/td/input[@type="Button"]/@value["'+ buttonName +'"]')
            else:
                raise Exception("Invalid value for action parameter")

        elif order = 'Last':
            self.find_element('//*[starts-with(@id,"table_")]/tbody/tr[last()]/td[text()= "'+ searchValue +'"]')
            if action == "Link":
                self.click(10, "//*[starts-with(@id,'table_')]/tbody/tr[last()]")
            elif action == "Checkbox":
                self.click(10, '//*[starts-with(@id,"table_")]/tbody/tr[last()]/td/input[@type="checkbox"]')
            elif action == "Button" and buttonName:
                self.click(10, '//*[starts-with(@id,"table_")]/tbody/tr[last()]/td/input[@type="Button"]/@value["'+ buttonName +'"]')
            else:
                raise Exception("Invalid value for action parameter")

        else:
            raise Exception("Invalid value for order parameter") 

1 Answer 1

1

You should really try using the Page Object pattern - defining the pages, parts of pages as page objects abstracting away the way locating the elements and available actions on a page.

For example, in your case you might have a table row defined as a separate object:

INDEX_MAP = {
    'First': '1',
    'Last': 'last()'
}

class RowElement(object):
    def __init__(self, driver, index):
        if index not in INDEX_MAP:
            raise ValueError("Invalid index %s" % index)

        self.driver = driver
        self.row = self.driver.find_element_by_xpath("//*[starts-with(@id,'table_')]/tbody/tr[%s]" % INDEX_MAP[index])

    def click_checkbox(self):
        self.row.find_element_by_xpath('./td/input[@type="checkbox"]').click()

    def click_button(self, name):
        self.row.find_element_by_xpath('./td/input[@type="Button" and @value = "%s"]' % name).click()

Then, you can use this RowElement class this way:

row = RowElement(driver, 'First')
row.click_checkbox()
row.click_button("Apply")

row = RowElement(driver, 'Last')
row.click_checkbox()
row.click_button("Apply")
Sign up to request clarification or add additional context in comments.

3 Comments

great this is so much cleaner. awesome thanks a lot.
just a last question, The way i written the xpath with using the parameter - '//*[starts-with(@id,"table_")]/tbody/tr[1]/td/input[@type="Button"]/@value["'+ buttonName +'"]. Is this not a good way?
@user7242550 yeah, if you want to match the button by the "value" attribute - then this is not the correct way to do that. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.