Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/feature_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- name: Set up uv
uses: SFDO-Tooling/setup-uv@main
with:
version: "0.5.0"
version: "0.6.1"
enable-cache: true
- name: Install dependencies
run: uv sync --group docs
Expand All @@ -56,7 +56,7 @@ jobs:
- name: Set up uv
uses: SFDO-Tooling/setup-uv@main
with:
version: "0.5.0"
version: "0.6.1"
enable-cache: true
- name: Install dependencies
run: uv sync -p ${{ matrix.python-version }}
Expand All @@ -80,7 +80,7 @@ jobs:
- name: Set up uv
uses: SFDO-Tooling/setup-uv@main
with:
version: "0.5.0"
version: "0.6.1"
enable-cache: true
- name: Install dependencies
run: uv sync --all-extras -p ${{ matrix.python-version }}
Expand All @@ -99,7 +99,7 @@ jobs:
- name: Set up uv
uses: SFDO-Tooling/setup-uv@main
with:
version: "0.5.0"
version: "0.6.1"
enable-cache: true
- name: Install dependencies
run: uv sync -p 3.11
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release_test_sfdx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
- name: Set up uv
uses: SFDO-Tooling/setup-uv@main
with:
version: "0.5.0"
version: "0.6.1"
enable-cache: true
- name: Install Python dependencies
run: uv sync
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/slow_integration_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
- name: Set up uv
uses: SFDO-Tooling/setup-uv@main
with:
version: "0.5.0"
version: "0.6.1"
enable-cache: true
- name: Install dependencies
run: uv sync -p 3.11
Expand Down
13 changes: 7 additions & 6 deletions cumulusci/robotframework/Salesforce.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
StaleElementReferenceException,
WebDriverException,
)
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from SeleniumLibrary.errors import ElementNotFound, NoOpenBrowser
from selenium.webdriver.common.by import By
from urllib3.exceptions import ProtocolError

from cumulusci.robotframework import locator_manager
Expand Down Expand Up @@ -607,7 +609,7 @@ def select_app_launcher_app(self, app_name, timeout=30):
self.selenium.wait_until_page_contains_element(locator, timeout)
self.selenium.set_focus_to_element(locator)
elem = self.selenium.get_webelement(locator)
link = elem.find_element_by_xpath("../../..")
link = elem.find_element(By.XPATH, "../../..")
self.selenium.set_focus_to_element(link)
link.click()
self.wait_until_modal_is_closed()
Expand Down Expand Up @@ -892,7 +894,8 @@ def _locate_element_by_label(self, browser, locator, tag, constraints):
fieldset_prefix
+ f'//label[descendant-or-self::*[text()[normalize-space() = "{label}"]]]'
)
labels = browser.find_elements_by_xpath(label_xpath)
labels = browser.find_elements(By.XPATH, label_xpath)

if not labels:
return []

Expand All @@ -906,13 +909,11 @@ def _locate_element_by_label(self, browser, locator, tag, constraints):
# probably never be. Famous last words, right?
orig_wait = self.selenium.set_selenium_implicit_wait(0)
component = None
component = label_element.find_element_by_xpath(
"./ancestor::*[starts-with(local-name(), 'lightning-')][1]"
)
component = label_element.find_element(By.XPATH, "./ancestor::*[starts-with(local-name(), 'lightning-')][1]")
except NoSuchElementException:
component_id = label_element.get_attribute("for")
if component_id:
component = browser.find_element_by_id(component_id)
component = browser.find_element(By.ID, component_id)
# else find an input or textarea in a sibling or descendant?
finally:
self.selenium.set_selenium_implicit_wait(orig_wait)
Expand Down
2 changes: 1 addition & 1 deletion cumulusci/robotframework/Salesforce.robot
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ Chrome Set Headless
... This keyword is not intended to be used by test scripts

[Arguments] ${options}
Call Method ${options} set_headless ${true}
Call Method ${options} add_argument --headless
Call Method ${options} add_argument --disable-dev-shm-usage
Call Method ${options} add_argument --disable-background-timer-throttling
[return] ${options}
10 changes: 4 additions & 6 deletions cumulusci/robotframework/form_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from robot.libraries.BuiltIn import BuiltIn
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By

from cumulusci.utils.classutils import get_all_subclasses

Expand Down Expand Up @@ -61,9 +62,7 @@ def selenium(self):
@property
def input_element(self):
"""Returns the first <input> or <textarea> element inside the element"""
elements = self.element.find_elements_by_xpath(
".//*[self::input or self::textarea]"
)
elements = self.element.find_elements(By.XPATH, ".//*[self::input or self::textarea]")
return elements[0] if elements else None

@abc.abstractmethod
Expand Down Expand Up @@ -130,9 +129,8 @@ class LightningComboboxHandler(BaseFormHandler):
@property
def input_element(self):
"""Returns the base form element (input or button) that the combobox is based on"""
elements = self.element.find_elements_by_xpath(
".//*[contains(@class, 'slds-combobox__input')]"
)
elements = self.element.find_elements(By.XPATH, ".//*[contains(@class, 'slds-combobox__input')]")

return elements[0] if elements else None

def set(self, value):
Expand Down
16 changes: 9 additions & 7 deletions cumulusci/robotframework/pageobjects/BasePageObjects.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

from selenium.common.exceptions import NoSuchElementException, TimeoutException
from SeleniumLibrary.errors import ElementNotFound
from selenium.webdriver.common.by import By


from cumulusci.robotframework.form_handlers import get_form_handler
from cumulusci.robotframework.pageobjects import BasePage, pageobject
Expand Down Expand Up @@ -73,7 +75,7 @@ def select_rows(self, *items):
elements = self.selenium.get_webelements(xpath)
if elements:
for element in elements:
cb = element.find_element_by_tag_name("input")
cb = element.find_element(By.TAG_NAME, "input")
if not cb.is_selected():
element.click()
else:
Expand Down Expand Up @@ -103,7 +105,7 @@ def deselect_rows(self, *items):

if elements:
for element in elements:
cb = element.find_element_by_tag_name("input")
cb = element.find_element(By.TAG_NAME, "input")
if cb.is_selected():
self.builtin.log(f"clicking on element for {item}")
element.click()
Expand Down Expand Up @@ -253,15 +255,15 @@ def _get_form_element_for_label(self, label):
"""
# search from the root of the document, unless a modal
# is open
root = self.selenium.driver.find_element_by_tag_name("body")
root = self.selenium.driver.find_element(By.TAG_NAME, "body")
with self._no_implicit_wait():
# We don't want to wait, we just want to know if the
# modal is alredy there or not. The caller should have
# already waited for the modal.

# also, we use find_elements (plural) here because it will
# return an empty list rather than throwing an error
modals = root.find_elements_by_xpath("//div[contains(@class, 'uiModal')]")
modals = root.find_element(By.XPATH, "//div[contains(@class, 'uiModal')]")
# There should only ever be zero or one, but the Salesforce
# UI never ceases to surprise me.
modals = [m for m in modals if m.is_displayed()]
Expand All @@ -272,9 +274,9 @@ def _get_form_element_for_label(self, label):
# where "for" points to the associated input field. w00t! If we can,
# use that. If not, fall back to an older strategy
try:
label_element = root.find_element_by_xpath(f'//label[text()="{label}"]')
label_element = root.find_element(By.XPATH, f'//label[text()="{label}"]')
input_id = label_element.get_attribute("for")
element = root.find_element_by_id(input_id)
element = root.find_element(By.ID, input_id)
return element

except NoSuchElementException:
Expand All @@ -285,7 +287,7 @@ def _get_form_element_for_label(self, label):
# has a child element with the class 'form-element__label' and
# text that matches the given label.
locator = f".//*[contains(@class, 'slds-form-element') and .//*[contains(@class, 'form-element__label')]/descendant-or-self::text()='{label}']"
element = root.find_element_by_xpath(locator)
element = root.find_element(By.XPATH, locator)
return element

except NoSuchElementException:
Expand Down
2 changes: 1 addition & 1 deletion cumulusci/robotframework/tests/salesforce/forms.robot
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ Lightning based form - radiobutton
# Using the label: locator returns a lightning-input element. We need to find
# the actual html input element to verify that it is checked. Ugly, but efficient.
${element}= Get webelement label:All users can see this list view
Should be true ${element.find_element_by_xpath(".//input").is_selected()}
Should be true ${element.find_element(By.XPATH, ".//input").is_selected()}

Non-lightning based form - radiobutton
[Documentation] Verify we can set a plain non-lightning radiobutton
Expand Down
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,14 @@ dependencies = [
"rich>=13.9.4",
"robotframework",
"SQLAlchemy<2",
"robotframework-browser",
"robotframework-pabot",
"robotframework-requests",
"robotframework-seleniumlibrary<6",
"robotframework-seleniumlibrary",
"rst2ansi>=0.1.5",
"salesforce-bulk",
"sarge",
"selenium<4",
"selenium",
"simple-salesforce==1.11.4",
"snowfakery>=4.0.0",
"xmltodict",
Expand Down
Loading
Loading