optimize react select (#654)

This commit is contained in:
LawyZheng 2024-07-29 15:32:16 +08:00 committed by GitHub
parent 1629d84375
commit f771cbb340
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 35 additions and 6 deletions

View file

@ -696,6 +696,9 @@ async function getSelect2Options(element) {
} }
async function getReactSelectOptionElements(element) { async function getReactSelectOptionElements(element) {
var scrollLeft = window.scrollX;
var scrollTop = window.scrollY;
let optionList = []; let optionList = [];
// wait for 2s until the element is updated with `aria-controls` // wait for 2s until the element is updated with `aria-controls`
console.log("wait 2s for the dropdown being updated."); console.log("wait 2s for the dropdown being updated.");
@ -714,7 +717,7 @@ async function getReactSelectOptionElements(element) {
// sometimes need more time to load the options // sometimes need more time to load the options
console.log("wait 5s to load all options"); console.log("wait 5s to load all options");
await sleep(5000); // wait 5s await sleep(5000); // wait 5s
optionList = dropdownDiv.querySelectorAll("div[role='option']"); optionList = dropdownDiv.querySelectorAll("div[class*='select__option']");
if (optionList.length === 0) { if (optionList.length === 0) {
break; break;
} }
@ -750,6 +753,12 @@ async function getReactSelectOptionElements(element) {
); );
} }
// scroll back to the original place
window.scroll({
top: scrollTop,
left: scrollLeft,
behavior: "instant",
});
return optionList; return optionList;
} }
@ -887,6 +896,12 @@ async function buildTreeFromBody(frame = "main.frame", open_select = false) {
view: window, view: window,
}), }),
); );
element.dispatchEvent(
new MouseEvent("mousedown", {
bubbles: true,
view: window,
}),
);
selectOptions = await getReactSelectOptions(element); selectOptions = await getReactSelectOptions(element);
@ -897,6 +912,19 @@ async function buildTreeFromBody(frame = "main.frame", open_select = false) {
view: window, view: window,
}), }),
); );
element.dispatchEvent(
new MouseEvent("mousedown", {
bubbles: true,
view: window,
}),
);
element.dispatchEvent(
new KeyboardEvent("keydown", {
keyCode: 27,
bubbles: true,
key: "Escape",
}),
);
} else if (open_select && isComboboxDropdown(element)) { } else if (open_select && isComboboxDropdown(element)) {
// open combobox dropdown to get options // open combobox dropdown to get options
element.click(); element.click();

View file

@ -440,7 +440,7 @@ class ReactSelectDropdown(AbstractSelectDropdown):
locator = self.skyvern_element.get_locator() locator = self.skyvern_element.get_locator()
if tag_name == InteractiveElement.BUTTON: if tag_name == InteractiveElement.BUTTON:
return locator.locator("..").locator("..").locator("input[class~='select__input']") return locator.locator("..").locator("..").locator("input[class*='select__input']")
return locator return locator
@ -461,17 +461,18 @@ class ReactSelectDropdown(AbstractSelectDropdown):
return "react-select" return "react-select"
async def open(self, timeout: float = SettingsManager.get_settings().BROWSER_ACTION_TIMEOUT_MS) -> None: async def open(self, timeout: float = SettingsManager.get_settings().BROWSER_ACTION_TIMEOUT_MS) -> None:
await self.skyvern_element.get_locator().click(timeout=timeout) await self.skyvern_element.get_locator().focus(timeout=timeout)
await self.skyvern_element.get_locator().press(key="ArrowDown", timeout=timeout)
await self.__find_anchor(timeout=timeout) await self.__find_anchor(timeout=timeout)
async def close(self, timeout: float = SettingsManager.get_settings().BROWSER_ACTION_TIMEOUT_MS) -> None: async def close(self, timeout: float = SettingsManager.get_settings().BROWSER_ACTION_TIMEOUT_MS) -> None:
await self.__find_anchor(timeout=timeout) await self.__find_anchor(timeout=timeout)
await self.skyvern_element.get_locator().click(timeout=timeout) await self.skyvern_element.get_locator().press(key="Escape", timeout=timeout)
async def get_current_value(self, timeout: float = SettingsManager.get_settings().BROWSER_ACTION_TIMEOUT_MS) -> str: async def get_current_value(self, timeout: float = SettingsManager.get_settings().BROWSER_ACTION_TIMEOUT_MS) -> str:
input_locator = self.__find_input_locator() input_locator = self.__find_input_locator()
# TODO: only support single value now # TODO: only support single value now
value_locator = input_locator.locator("..").locator("..").locator("div[class~='select__single-value']") value_locator = input_locator.locator("..").locator("..").locator("div[class*='select__single-value']")
if await value_locator.count() == 0: if await value_locator.count() == 0:
return "" return ""
try: try:
@ -491,7 +492,7 @@ class ReactSelectDropdown(AbstractSelectDropdown):
self, index: int, timeout: float = SettingsManager.get_settings().BROWSER_ACTION_TIMEOUT_MS self, index: int, timeout: float = SettingsManager.get_settings().BROWSER_ACTION_TIMEOUT_MS
) -> None: ) -> None:
anchor = await self.__find_anchor(timeout=timeout) anchor = await self.__find_anchor(timeout=timeout)
options = anchor.locator("div[role='option']") options = anchor.locator("div[class*='select__option']")
await options.nth(index).click(timeout=timeout) await options.nth(index).click(timeout=timeout)