Skip to content
Open
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
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ For example:
* Ben French (BenjaminFrench)
* Rupert Barrow (rupertbarrow)
* Rupesh J (rupeshjSFDC)
* Bhimeswara Vamsi Punnam (b-vamsipunnam)
58 changes: 58 additions & 0 deletions cumulusci/robotframework/Salesforce.py
Original file line number Diff line number Diff line change
Expand Up @@ -934,3 +934,61 @@ def select_window(self, locator="MAIN", timeout=None):
"'Select Window' is deprecated; use 'Switch Window' instead", "WARN"
)
self.selenium.switch_window(locator=locator, timeout=timeout)

@capture_screenshot_on_error
def get_all_picklist_values(self, name, timeout="10s"):
"""Return available non-empty values from a Salesforce Lightning picklist.

Opens the picklist identified by its visible field label and returns
the non-empty option values currently rendered in the Lightning picklist.

Examples:
| ${values}= | Get All Picklist Values | Stage |
| ${values}= | Get All Picklist Values | Lead Status | timeout=15s |
"""
picklist_locator = f"label:{name}"
option_xpath = (
"xpath://lightning-base-combobox-item"
"//span[contains(@class,'slds-media__body') or @slot='label']"
)

try:
self.selenium.set_focus_to_element(picklist_locator)
self.scroll_element_into_view(picklist_locator)
self.selenium.click_element(picklist_locator)
self.selenium.wait_until_element_is_visible(
option_xpath,
timeout=timeout,
)

values = []
for element in self.selenium.get_webelements(option_xpath):
try:
text = element.text.strip()
if text:
values.append(text)
except (
StaleElementReferenceException,
WebDriverException,
):
continue

self.builtin.log(
f"Retrieved {len(values)} values from picklist '{name}'.",
"INFO",
)
return values

except ElementNotFound:
raise AssertionError(
f"Picklist '{name}' was not found on the page."
) from None

finally:
try:
self.selenium.press_keys(None, "ESC")
except Exception as err:
self.builtin.log(
f"Failed to close picklist dropdown: {err}",
"DEBUG",
)
63 changes: 63 additions & 0 deletions cumulusci/robotframework/tests/salesforce/picklist.robot
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
*** Settings ***
Documentation
... This suite tests the `Get All Picklist Values` keyword.
... Specifically, it verifies that the keyword can open a Salesforce
... Lightning picklist and return the available option values.

Library String
Library DateTime
Library Collections
Resource cumulusci/robotframework/Salesforce.robot

Suite Setup run keywords
... Open test browser
... AND Create opportunity
Suite Teardown Delete Records and Close Browser


*** Keywords ***
Create opportunity
[Documentation]
... Creates a test opportunity with a random name and a close
... date 30 days in the future. A reference to the created
... opportunity will be stored in the suite variable ${opportunity}.

${30 days from now}= Get Current Date increment=30 days result_format=%Y-%m-%d
${random}= Generate random string 8 [NUMBERS]
${opportunity_id}= Salesforce Insert Opportunity
... Name=Picklist Test ${random}
... CloseDate=${30 days from now}
... Amount=100000
... Probability=42
... StageName=Prospecting
... Description=Picklist keyword test
&{opportunity}= Salesforce Get Opportunity ${opportunity_id}
set suite variable ${opportunity}
[Return] ${opportunity}


*** Test Cases ***
Test Get All Picklist Values
[Documentation]
... Verify that Get All Picklist Values returns available values
... from a Lightning picklist field.

[Setup] run keywords
... go to object home Opportunity
... AND click link ${opportunity['Name']}
... AND click object button Edit
... AND wait until modal is open

${values}= Get All Picklist Values Stage
Log ${values}

Run keyword and continue on failure
... Should Not Be Empty
... ${values}
... Expected Stage picklist values to be returned but received an empty list

Run keyword and continue on failure
... List Should Contain Value
... ${values}
... Prospecting
... Expected Stage picklist to contain 'Prospecting' but values were '${values}'
72 changes: 72 additions & 0 deletions cumulusci/robotframework/tests/test_salesforce.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from SeleniumLibrary.errors import ElementNotFound

from cumulusci.robotframework.Salesforce import Salesforce
from selenium.common.exceptions import StaleElementReferenceException


# _init_locators has a special code block
Expand Down Expand Up @@ -77,3 +78,74 @@ def setup_class(cls):
def test_breakpoint(self, mock_robot_context):
"""Verify that the keyword doesn't raise an exception"""
assert self.sflib.breakpoint() is None


@mock.patch("robot.libraries.BuiltIn.BuiltIn._get_context")
class TestKeywordGetAllPicklistValues:
@classmethod
def setup_class(cls):
cls.sflib = Salesforce(locators={"body": "//whatever"})

def test_returns_rendered_non_empty_picklist_values(self, mock_robot_context):
option_1 = mock.Mock(text="Warm")
option_2 = mock.Mock(text="Cold")
option_3 = mock.Mock(text="Warm")
option_4 = mock.Mock(text=" ")

with mock.patch.object(self.sflib, "scroll_element_into_view"):
self.sflib.selenium.get_webelements.return_value = [
option_1,
option_2,
option_3,
option_4,
]

values = self.sflib.get_all_picklist_values("Status")

assert values == ["Warm", "Cold", "Warm"]

self.sflib.selenium.set_focus_to_element.assert_called_once_with("label:Status")
self.sflib.selenium.click_element.assert_called_once_with("label:Status")
self.sflib.selenium.wait_until_element_is_visible.assert_called_once()
self.sflib.selenium.press_keys.assert_any_call(None, "ESC")

def test_ignores_stale_options(self, mock_robot_context):
good_option = mock.Mock(text="Active")

stale_option = mock.Mock()
type(stale_option).text = mock.PropertyMock(
side_effect=StaleElementReferenceException()
)

with mock.patch.object(self.sflib, "scroll_element_into_view"):
self.sflib.selenium.get_webelements.return_value = [
stale_option,
good_option,
]

values = self.sflib.get_all_picklist_values("Status")

assert values == ["Active"]

def test_raises_assertion_when_picklist_not_found(self, mock_robot_context):
with mock.patch.object(
self.sflib.selenium,
"set_focus_to_element",
side_effect=ElementNotFound(),
):
with pytest.raises(
AssertionError,
match="Picklist 'Status' was not found on the page.",
):
self.sflib.get_all_picklist_values("Status")

def test_uses_custom_timeout(self, mock_robot_context):
option = mock.Mock(text="Active")

with mock.patch.object(self.sflib, "scroll_element_into_view"):
self.sflib.selenium.get_webelements.return_value = [option]

self.sflib.get_all_picklist_values("Status", timeout="15s")

_, kwargs = self.sflib.selenium.wait_until_element_is_visible.call_args
assert kwargs["timeout"] == "15s"