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
3 changes: 3 additions & 0 deletions .vscode-test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ export default defineConfig({
"--disable-extension=ritwickdey.liveserver",
"--disable-extension=streetsidesoftware.code-spell-checker",
],
download: {
timeout: 60_000,
},
mocha: {
color: true,
ui: "bdd",
Expand Down
9 changes: 5 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# cspell: ignore healthcheck
services:
selenium-vscode:
image: ghcr.io/ansible/selenium-adt:main
image: ghcr.io/ansible/selenium-adt:26.4.0
pull_policy: missing
container_name: selenium-vscode
shm_size: "10g"
Expand All @@ -13,18 +13,19 @@ services:
ports:
- "4444:4444"
- "5999:5999"
- "127.0.0.1:8080:8080"
volumes:
# apparently podman does not want to mount file as container root
- ${VSX_FILE:-./out/data/ansible-latest.vsix}:/data/ansible-latest.vsix:ro
- ./.vscode-test/user-data/User/settings.json:/home/selenium/.local/share/code-server/User/settings.json:rw
- ./out/ui/logs:/home/selenium/.local/share/code-server/logs:rw
restart: "no"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:4444"]
test: ["CMD-SHELL", "curl -sf --max-time 3 http://localhost:4444 && curl -sf --max-time 3 http://localhost:8080"]
interval: 10s
timeout: 5s
retries: 10
start_period: 10s
retries: 30
start_period: 30s
deploy:
resources:
limits:
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,9 @@
"mocha": "*"
}
}
},
"patchedDependencies": {
"@vscode/test-cli@0.0.12": "patches/@vscode__test-cli@0.0.12.patch"
}
},
"scripts": {
Expand Down
14 changes: 14 additions & 0 deletions patches/@vscode__test-cli@0.0.12.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
diff --git a/out/cli/platform/desktop.mjs b/out/cli/platform/desktop.mjs
index b901849b00f8072284a225ab703460e21425fcfc..50b5bcc3d7b7eb4c6f8ecb6ab91dd124af79109a 100644
--- a/out/cli/platform/desktop.mjs
+++ b/out/cli/platform/desktop.mjs
@@ -126,7 +126,8 @@ class PreparedDesktopRun {
return;
}
const opts = this.baseCliOptions();
- const vscodePath = await electron.downloadAndUnzipVSCode(opts.version, opts.platform, opts.reporter);
+ // https://github.com/microsoft/vscode-test-cli/issues/106
+ const vscodePath = await electron.downloadAndUnzipVSCode(opts);
const [cli, ...cliArgs] = electron.resolveCliArgsFromVSCodeExecutablePath(vscodePath, opts);
for (const extension of exts.value) {
cliArgs.push('--install-extension', extension);
9 changes: 7 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 40 additions & 4 deletions test/ui/fixtures/ui_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def browser_setup(
"capturemanager"
) # type: ignore[name-defined]
try:
if not is_container_healthy() or True:
if not is_container_healthy():
subprocess.run(
f"podman rm -f {CONTAINER_NAME} 2>/dev/null || true",
shell=True,
Expand All @@ -80,14 +80,43 @@ def browser_setup(
shell=True,
cwd=_PROJECT_ROOT,
)
health_timeout_raw = os.environ.get(
"UI_CONTAINER_HEALTH_TIMEOUT",
"360",
)
try:
health_timeout = int(health_timeout_raw)
except ValueError:
pytest.fail(
f"Invalid UI_CONTAINER_HEALTH_TIMEOUT={health_timeout_raw!r}; "
"expected an integer number of seconds",
)
start = time.time()
deadline = start + health_timeout
count = 0
while True:
while time.time() < deadline:
if is_container_healthy():
elapsed = int(time.time() - start)
log.info(
"Container %s healthy after %ss (%s checks)",
CONTAINER_NAME,
elapsed,
count + 1,
)
break
count += 1
time.sleep(1)
elapsed = int(time.time() - start)
log.info(
"Waiting for container %s to be healthy: %s", CONTAINER_NAME, count
"Waiting for container %s to be healthy: check %s (%ss elapsed)",
CONTAINER_NAME,
count,
elapsed,
)
time.sleep(2)
else:
pytest.fail(
f"container {CONTAINER_NAME} did not become healthy "
f"within {health_timeout}s",
)

browser = os.environ.get("BROWSER_TYPE")
Expand All @@ -103,7 +132,12 @@ def browser_setup(
command_executor="http://localhost:4444/wd/hub",
options=options,
)
driver.set_page_load_timeout(120)
driver.set_script_timeout(60)
Comment thread
cidrblock marked this conversation as resolved.
driver.maximize_window()
log.info(
"Browser connected, starting UI tests (no output until completion)",
)

yield driver, "https://stage.ai.ansible.redhat.com/login"
close_all_tabs(driver)
Expand Down Expand Up @@ -138,6 +172,8 @@ def new_browser() -> Generator[tuple[WebDriver | None, str, None], None, None]:
driver = WebDriver(
command_executor="http://localhost:4444/wd/hub", options=options
)
driver.set_page_load_timeout(120)
driver.set_script_timeout(60)
driver.maximize_window()
yield driver, "https://stage.ai.ansible.redhat.com/login", None
finally:
Expand Down
58 changes: 31 additions & 27 deletions test/ui/utils/ui_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# pylint: disable=E0401
import contextlib
import logging
import os
import time
from collections.abc import Generator
Expand All @@ -28,6 +29,8 @@
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.ui import WebDriverWait

log = logging.getLogger(__name__)

LIGHTSPEED_USER = os.environ.get("LIGHTSPEED_USER", "")
LIGHTSPEED_PASSWORD = os.environ.get("LIGHTSPEED_PASSWORD", "")

Expand Down Expand Up @@ -77,14 +80,20 @@ def ensure_vscode_ready(driver: WebDriver, timeout: int = 120) -> None:
"""
driver.switch_to.default_content()
if "127.0.0.1:8080" not in driver.current_url:
log.info("Navigating to code-server at http://127.0.0.1:8080")
driver.get("http://127.0.0.1:8080")
log.info("Page loaded successfully")
log.info("Waiting for Ansible sidebar icon (up to 60s)")
wait_displayed(driver, "//a[@aria-label='Ansible']", timeout=60)
log.info("Sidebar icon found, focusing ADT view")
vscode_run_command(driver, ">Ansible: Focus on Ansible Development Tools View")
log.info("Waiting for extension activation (welcome page, up to %ss)", timeout)
find_element_across_iframes(
driver,
"//a[contains(@title, 'Ansible Development Tools welcome page')]",
retries=timeout,
)
log.info("Extension ready")


def click_and_wait(
Expand Down Expand Up @@ -1021,42 +1030,37 @@ def vscode_run_command(
if not command.startswith(">"):
command = ">" + command

# Dismiss any leftover palette/dialog from a previous call to avoid
# blocking the command-center click with an overlay.
ActionChains(driver).send_keys(Keys.ESCAPE).perform()
time.sleep(0.3)

# click the command box
max_attempts = 6 # we seen timeout issue on GHA with 4 seconds
log.info("Opening command palette via F1 for: %s", command)
max_attempts = 3
command_input = None
for i in range(max_attempts):
ActionChains(driver).send_keys(Keys.F1).perform()
try:
command_box = find_element_across_iframes(
driver,
"//li[@class='action-item command-center-center']",
)
command_input = click_and_wait(
driver,
command_box,
"//input[@aria-controls='quickInput_list']",
timeout=2,
command_input = WebDriverWait(driver, timeout=5).until(
expected_conditions.visibility_of_element_located(
(By.XPATH, "//input[@aria-controls='quickInput_list']"),
),
)
break
except (
TimeoutException,
TimeOutError,
NoSuchElementException,
StaleElementReferenceException,
): # pragma: no cover
if i == max_attempts - 1:
raise
time.sleep(1)
except TimeoutException: # pragma: no cover
log.warning(
"Command palette did not open on attempt %s/%s",
i + 1,
max_attempts,
)
ActionChains(driver).send_keys(Keys.ESCAPE).perform()
time.sleep(0.5)

if command_input:
command_input.send_keys(command)
# Let the palette finish filtering results before pressing Enter,
# otherwise the keystroke can arrive before a match is highlighted.
time.sleep(0.5)
if not command_input:
msg = f"Command palette failed to open after {max_attempts} attempts"
raise TimeoutException(msg)

command_input.send_keys(command)
time.sleep(0.5)
log.info("Command entered, pressing Enter")
actions = ActionChains(driver)
actions.send_keys(Keys.ENTER).perform()
if command_param:
Expand Down
Loading