Skip to content
Merged
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 .gitlab/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,6 @@
azurite:
name: registry.ddbuild.io/images/mirror/azure-storage/azurite:3.34.0
alias: azurite
selenium-chrome:
name: registry.ddbuild.io/images/mirror/selenium/standalone-chrome:latest
alias: selenium-chrome
9 changes: 9 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,15 @@ services:
- "127.0.0.1:10002:10002"


selenium-chrome:
image: selenium/standalone-chrome:latest
platform: linux/amd64
network_mode: host
environment:
- SE_NODE_MAX_SESSIONS=2
- SE_VNC_NO_PASSWORD=1
shm_size: 2g

testrunner:
# DEV uncomment to test local changes to the Dockerfile
# build:
Expand Down
4 changes: 4 additions & 0 deletions tests/ci_visibility/suitespec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ suites:
snapshot: true
selenium:
parallelism: 2
env:
SELENIUM_GRID_URL: http://selenium-chrome:4444
paths:
- '@bootstrap'
- '@core'
Expand All @@ -170,6 +172,8 @@ suites:
- tests/contrib/selenium/*
- tests/snapshots/test_selenium*
snapshot: true
services:
- selenium-chrome
unittest:
parallelism: 2
paths:
Expand Down
143 changes: 65 additions & 78 deletions tests/contrib/selenium/test_selenium_chrome.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
"""Tests for selenium + RUM integration

IMPORTANT NOTE: these tests only reliably work on Linux/x86_64 due to some annoyingly picky issues with installing
Selenium and a working browser/webdriver combination on non-x86_64 architectures (at time of writing, at least,
Selenium's webdriver-manager doesn't support Linux on non-x86_64).
Uses a Selenium Grid (selenium/standalone-chrome, linux/amd64) via webdriver.Remote so that
tests work on any host architecture including arm64. The grid URL is controlled by the
SELENIUM_GRID_URL environment variable (default: http://localhost:4444 for local runs via
docker-compose network_mode: host; set to http://selenium-chrome:4444 in CI).
"""

import http.server
import json
import multiprocessing
import os
from pathlib import Path
import platform
import socketserver
import subprocess
import textwrap
Expand Down Expand Up @@ -45,6 +45,23 @@
"start",
]

# Selenium Grid endpoint — standalone-chrome runs with network_mode: host so it binds on localhost
SELENIUM_GRID_URL = os.environ.get("SELENIUM_GRID_URL", "http://localhost:4444")

_SELENIUM_DRIVER_SETUP = f"""\
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options

SELENIUM_GRID_URL = "{SELENIUM_GRID_URL}"

def _make_driver():
options = Options()
options.add_argument("--headless")
options.add_argument("--no-sandbox")
return webdriver.Remote(command_executor=SELENIUM_GRID_URL, options=options)
"""


@pytest.fixture
def _http_server(scope="function"):
Expand Down Expand Up @@ -74,39 +91,29 @@ def _run_server():


@snapshot(ignores=SELENIUM_SNAPSHOT_IGNORES)
@pytest.mark.skipif(platform.machine() != "x86_64", reason="Selenium Chrome tests only run on x86_64")
def test_selenium_chrome_pytest_rum_enabled(_http_server, testdir, git_repo):
selenium_test_script = textwrap.dedent(
"""
from pathlib import Path
_SELENIUM_DRIVER_SETUP
+ """
def test_selenium_local_pass():
with _make_driver() as driver:
url = "http://localhost:8079/rum_enabled/page_1.html"
Comment thread
gnufede marked this conversation as resolved.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
driver.get(url)

def test_selenium_local_pass():
options = Options()
options.add_argument("--headless")
options.add_argument("--no-sandbox")
assert driver.title == "Page 1"

with webdriver.Chrome(options=options) as driver:
url = "http://localhost:8079/rum_enabled/page_1.html"
link_2 = driver.find_element(By.LINK_TEXT, "Page 2")

driver.get(url)
link_2.click()

assert driver.title == "Page 1"
assert driver.title == "Page 2"

link_2 = driver.find_element(By.LINK_TEXT, "Page 2")
link_1 = driver.find_element(By.LINK_TEXT, "Back to page 1.")
link_1.click()

link_2.click()

assert driver.title == "Page 2"

link_1 = driver.find_element(By.LINK_TEXT, "Back to page 1.")
link_1.click()

assert driver.title == "Page 1"
"""
assert driver.title == "Page 1"
"""
)
testdir.makepyfile(test_selenium=selenium_test_script)
subprocess.run(
Expand All @@ -127,39 +134,29 @@ def test_selenium_local_pass():


@snapshot(ignores=SELENIUM_SNAPSHOT_IGNORES)
@pytest.mark.skipif(platform.machine() != "x86_64", reason="Selenium Chrome tests only run on x86_64")
def test_selenium_chrome_pytest_rum_disabled(_http_server, testdir, git_repo):
selenium_test_script = textwrap.dedent(
"""
from pathlib import Path
_SELENIUM_DRIVER_SETUP
+ """
def test_selenium_local_pass():
with _make_driver() as driver:
url = "http://localhost:8079/rum_disabled/page_1.html"

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
driver.get(url)

def test_selenium_local_pass():
options = Options()
options.add_argument("--headless")
options.add_argument("--no-sandbox")
assert driver.title == "Page 1"

with webdriver.Chrome(options=options) as driver:
url = "http://localhost:8079/rum_disabled/page_1.html"
link_2 = driver.find_element(By.LINK_TEXT, "Page 2")

driver.get(url)
link_2.click()

assert driver.title == "Page 1"
assert driver.title == "Page 2"

link_2 = driver.find_element(By.LINK_TEXT, "Page 2")
link_1 = driver.find_element(By.LINK_TEXT, "Back to page 1.")
link_1.click()

link_2.click()

assert driver.title == "Page 2"

link_1 = driver.find_element(By.LINK_TEXT, "Back to page 1.")
link_1.click()

assert driver.title == "Page 1"
"""
assert driver.title == "Page 1"
"""
)
testdir.makepyfile(test_selenium=selenium_test_script)
subprocess.run(
Expand All @@ -180,42 +177,32 @@ def test_selenium_local_pass():


@snapshot(ignores=SELENIUM_SNAPSHOT_IGNORES)
@pytest.mark.skipif(platform.machine() != "x86_64", reason="Selenium Chrome tests only run on x86_64")
def test_selenium_chrome_pytest_unpatch_does_not_record_selenium_tags(_http_server, testdir, git_repo):
selenium_test_script = textwrap.dedent(
"""
from pathlib import Path
_SELENIUM_DRIVER_SETUP
+ """
from ddtrace.contrib.internal.selenium.patch import unpatch

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
def test_selenium_local_unpatch():
unpatch()
with _make_driver() as driver:
url = "http://localhost:8079/rum_disabled/page_1.html"

from ddtrace.contrib.internal.selenium.patch import unpatch
driver.get(url)

def test_selenium_local_unpatch():
unpatch()
options = Options()
options.add_argument("--headless")
options.add_argument("--no-sandbox")
assert driver.title == "Page 1"

with webdriver.Chrome(options=options) as driver:
url = "http://localhost:8079/rum_disabled/page_1.html"
link_2 = driver.find_element(By.LINK_TEXT, "Page 2")

driver.get(url)
link_2.click()

assert driver.title == "Page 1"
assert driver.title == "Page 2"

link_2 = driver.find_element(By.LINK_TEXT, "Page 2")
link_1 = driver.find_element(By.LINK_TEXT, "Back to page 1.")
link_1.click()

link_2.click()

assert driver.title == "Page 2"

link_1 = driver.find_element(By.LINK_TEXT, "Back to page 1.")
link_1.click()

assert driver.title == "Page 1"
"""
assert driver.title == "Page 1"
"""
)
testdir.makepyfile(test_selenium=selenium_test_script)
subprocess.run(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@
"_dd.tracer_kr": 1.0,
"_sampling_priority_v1": 1,
"process_id": 13623,
"test.source.end": 29,
"test.source.start": 7
"test.source.end": 31,
"test.source.start": 13
},
"duration": 1035420043,
"start": 1733243045320806200
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,8 @@
"_dd.tracer_kr": 1.0,
"_sampling_priority_v1": 1,
"process_id": 13453,
"test.source.end": 29,
"test.source.start": 7
"test.source.end": 31,
"test.source.start": 13
},
"duration": 1056245299,
"start": 1733243043078204615
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,8 @@
"_dd.tracer_kr": 1.0,
"_sampling_priority_v1": 1,
"process_id": 12386,
"test.source.end": 32,
"test.source.start": 9
"test.source.end": 34,
"test.source.start": 15
},
"duration": 534785315,
"start": 1733242640750308571
Expand Down
Loading