I am setting up an end-to-end testing framework with Selenium in Python. In order to click on DOM elements I have to define a lot of locators (like XPaths, CSS-selectors etc.) which are mostly constant.
However, there are some constants that vary in each run, so some content needs to be formatted in at runtime.
At the moment I have a basic locators.py file which organizes all of the constants in a view-corresponding way like this:
class Locators:
class LoginPage:
USERNAME_INPUT = "//input[@id='username']"
PASSWORD_INPUT = "//input[@id='password']"
LOGIN_BUTTON = "//button[text()='Login']"
# ...
class Homepage:
ACTION_BUTTON = lambda t: f"//buton[text()='{t}']"
# ...
# ...
This can then be used like this:
from locators import Locators
browser.click(Locators.LoginPage.USERNAME_INPUT)
browser.click(Locators.Homepage.ACTION_BUTTON(var))
The last example here (ACTION_BUTTON) is of most interest to me. Since e.g. PyCharm displays a PEP 8 warning that using lambdas is discouraged I wonder whether there is a more elegant way of handling such "formattable" constants?
Furthermore, I would like to be able to generalize e.g. all buttons to the outer class like this:
class Locators:
_BUTTON = lambda s: f"//button[text()='{s}']"
class LoginPage:
USERNAME_INPUT = "//input[@id='username']"
PASSWORD_INPUT = "//input[@id='password']"
LOGIN_BUTTON = _BUTTON("Login")
class Homepage:
ACTION_BUTTON = _BUTTON
But this gives a syntax error.