Brazen
Brazen

Reputation: 295

Storing a locator in a variable

I'm new to Python and I'm using a current Java Selenium project as sort of a learning experience converting it to Python.

In Java, I could do By buttonSaveLoc = By.id("save-button"); Then, it's easy to use this locator since you don't need to remember the locator data, nor the strategy. Is there an equivalent in Python?

EDIT:

I'm looking for the locator and not a web element so it can be used for multiple purposes, eg find_element(LOCATOR) or expected_conditions.some_condition(LOCATOR).

EXAMPLE:

// SomePageComponent.java
public class SomePageComponent extends Page {
  private static final By buttonSaveLoc = By.cssSelector("button[title='Save']");

  public void clickSaveButton() {
    clickElement(buttonSaveLoc);
  }
}

// Page.java
public class Page {
  public void clickElement(@NotNull By locator) {
    goWait().until(ExpectedConditions.elementToBeClickable(locator)).click();
  }
}
# somepagecomponent.py
class SomePageComponent(Page):
    def __init__(self, ctx):
        super().__init__(ctx)
        self.button_save_loc = (By.CSS_SELECTOR, 'button[title="Save"]')

    def save(self):
        self.click_element(*self.button_save_loc)

# page.py
class Page:
    def __init__(self, ctx):
        self.browser = ctx.browser
        self.timeout = ctx.browser_timeout

    def click_element(self, locator):
        wait = WebDriverWait(self.browser, self.timeout)
        wait.until(expected_conditions.element_to_be_clickable(locator)).click()

# scenario_steps.py
@when('the user saves something')
def step_impl(ctx):
    something = SomePageComponent(ctx)
    something.save()

The Python script fails ...

Note that in the Java example which works, wherever the locator is used, I don't need to remember the strategy to find it (by id, classname, whatever) and I don't need to remember the data (some id or css script).

Again, the reason I want the locator is for the expected condition element_to_be_clickable() which takes a locator, and not a web element. You can see its use in the snippet I posted.

Since this seemed hard to pick up on, I'm assuming I'm using this in Python entirely wrong, and there's another way in Python to do the same thing.

Upvotes: 3

Views: 1335

Answers (2)

JD2775
JD2775

Reputation: 3801

Your post is somewhat confusing, but the below would work the same basically...

Java

By buttonSaveLoc = By.id("save-button");
//re-use..
driver.findElement(buttonSaveLoc).click();
driver.findElement(buttonSaveLoc).sendKeys("abc");

Python

buttonSaveLoc = driver.find_element_by_id("save-button")
#re-use..
buttonSaveLoc.click()
buttonSaveLoc.send_keys("abc")

If you are looking to literally just store the locator itself then:

buttonSaveLoc = "save-button"
#re-use..
driver.find_element_by_id(buttonSaveLoc)

Upvotes: 1

vitaliis
vitaliis

Reputation: 4212

Yes, you just need to specify a variable type:

For id:

element = driver.find_element_by_id("locator id")

For xpath:

element = driver.find_element_by_xpath("xpath locator")

For css:

element = driver.find_element_by_css_selector("css locator")

You can find the full list here: https://selenium-python.readthedocs.io/locating-elements.html As you can see from find_element_by_id- by is already there. To store a locator as a string use locator = "locator id", so your locators list will be just strings which you will pass when needed.

Apart from this you can use which is similar to the one you are used to when running tests on Java. The example is taken from docs link above:

from selenium.webdriver.common.by import By

element = driver.find_element(By.XPATH, '//button[text()="Some text"]') 

Upvotes: 2

Related Questions