Currently to define a locator we use a tuple formed by strategy and locator_path:
"get.element.by.link": (By.XPATH, "//a[contains(@href, '%s')]")
The problem is that the code turn verbose when we need to interpolate %s in the locator_path we should do.
strategy, value = locators['get.element.by.link']
self.click((strategy, value % 'foo/bar'))
We can just create a specialized type from tuple as
class Locator(tuple):
"""A tuple that allows direct interpolation of second element"""
def __mod__(self, data):
strategy, value = self
return strategy, value % data
We should use the above type instead of a tuple in locators:
"get.element.by.link": Locator(By.XPATH, "//a[contains(@href, '%s')]")
and then we can do direct interpolation, saving us of defining extra strategy, value variables everytime
self.click(locators['get.element.by.link'] % 'foo/bar')
Also I found that in logs we get this:
2016-07-14 13:03:25 - robottelo.ui.locators - DEBUG - Accessing locator "contenthost.bulk_actions.via_katello_agent" by xpath: "//a[contains(@ng-click, "performViaKatelloAgent('%s', content)")]"
Look the %s in logs is not very informative, so if we specialize the Location tuple we can add a DEBUG message in the interpolation to help us figuring out exactly which locator is being accessed.
Comment from IRC by @elyezer
a even less verbose approach would be locators.get_element_by_link also if they are converted to attributes autocomplete can work pretty well
Nice idea I'll experiment turning locators in to models and instead of keys we use atrtibutes
(BTW: trying to keeping the current approach working with no breaks)
Most helpful comment
Also I found that in logs we get this:
Look the %s in logs is not very informative, so if we specialize the Location tuple we can add a DEBUG message in the interpolation to help us figuring out exactly which locator is being accessed.