7

I've written a code to test a page in python with selenium. The code works but now I'm trying to rewrite it better.
I have created a locators.py file as described in the following documentation: selenium python binding - page objects.
For simple locators this is straightforward. This is what I've done so far:

from selenium.webdriver.common.by import By

class PhotoHomePageLocators(object):
"""A class for photographer home page locators. All photographer interface home page locators should come here"""
add_new_project_btn = (By.CLASS_NAME, 'addProject')
view_all_projects_btn = (By.CLASS_NAME, 'viewAllProjects')


class NameCoverPageLocators(object):
"""A class for name and cover home page locators. All name and cover page locators should come here"""
project_name_txt_box = (By.XPATH, '//*[@id="rform_pt2_0"]')
client_name_txt_box = (By.XPATH, '//*[@id="rform_pt2_1"]')
client_email_txt_box = (By.XPATH, '//*[@id="rform_pt2_2"]')

but I have the following line in my code which I'm uncertain how to write so it fits the above syntax:

driver.find_element_by_class_name('coverUpload').find_element_by_class_name('pButton').click()

I'm locating a class within a class, there are several pButton classes in the page, but only one inside the coverUpload class.

2
  • 1
    try to avoid locators starting with //* whenever possible, they are very inefficient. Providing the name of tag is better. Or even better, when using @id, is using By.ID Commented Aug 14, 2016 at 15:34
  • Thank you, @KirilS. I'll have to replace those as well. I'm not sure I fully understand the structure of the xpath locator. but that's for a different question I guess. Commented Aug 14, 2016 at 16:17

6 Answers 6

1

You should be able to arrange the line you are asking about as follows:

someName = driver.find_element_by_class_name('coverUpload')
ButtonName = someName.find_element_by_class_name('pButton')
ButtonName.click()
Sign up to request clarification or add additional context in comments.

Comments

1

instead of 2 class search maybe you can use relative Xpath if That element is unique.

elem = driver.find_element(By.XPATH, '//*[@class="coverUpload"]//*[@class="pButton"]')
elem.click()

Comments

0

Use find_elements_by_class_name

Comments

0

I'd suggest using selenium's find_element_by_css_selector which allows for more robust and complex chaining of classes:

css_selector = '.coverUpload . pButton'
button = find_element_by_css_selector(css_selector)
button.click()

Note: css selectors can be brittle, so make sure you have either a resilient selection strategy.

Comments

0

The classes found in locators.py that were provided don't contain class attributes for locators of "coverUpload" nor "pButton" however, using one of the locators defined in the example, it would look like the below:

driver.find_element(*PhotoHomePageLocators.add_new_project_btn).click()

Assuming the intention was to click on the button that appears to "add a new project".

Comments

0

To find the button exactly with provided attributes, I'd use "button" instead of "*". I believe this is gonna be more efficient.

elem = driver.find_element(By.XPATH, '//button[@class="coverUpload"]//button[@class="pButton"]')

Comments

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.