Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature2 #8

Merged
merged 3 commits into from
Dec 4, 2024
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
22 changes: 21 additions & 1 deletion .github/workflows/selenium-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,24 @@ jobs:
OBI_PASSWORD: ${{ secrets.OBI_PASSWORD }}
BROWSER_NAME: firefox
run: |
pytest tests/test_login.py -sv --headless
pytest tests/test_login.py -sv --headless

# Step 5: Slack notification on success
- name: Notify Slack on Success
if: success()
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
run: |
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\":white_check_mark: Test pipeline succeeded in *${{ github.repository }}*. Branch: *${{ github.ref_name }}*\", \"username\":\"GitHub Actions\", \"icon_emoji\":\":rocket:\"}" \
$SLACK_WEBHOOK_URL

# Step 6: Slack notification on failure
- name: Notify Slack on Failure
if: failure()
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
run: |
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\":x: Test pipeline failed in *${{ github.repository }}*. Branch: *${{ github.ref_name }}*. Check the logs for details.\", \"username\":\"GitHub Actions\", \"icon_emoji\":\":warning:\"}" \
$SLACK_WEBHOOK_URL
97 changes: 64 additions & 33 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,6 @@ def setup(request, pytestconfig):
else:
raise ValueError("Invalid BROWSER_NAME: {}".format(browser_name))

# elif browser_name == "headless":
# options.add_argument("--headless")
# options.add_argument("--no-sandbox")
# options.add_argument("--disable-gpu")
# service = ChromeService(ChromeDriverManager().install())
# browser = webdriver.Chrome(service=service, options=options)

wait = WebDriverWait(browser, 10)

if browser is not None:
Expand Down Expand Up @@ -175,8 +168,10 @@ def login(setup, navigate_to_login):
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item):
"""
Extends the PyTest Plugin to take and embed screenshot in html report, whenever test fails.
:param item:
Pytest hook implementation to handle test reporting.

- Captures screenshots when a test fails.
- Embeds the screenshot into the HTML report.
"""
pytest_html = item.config.pluginmanager.getplugin('html')
outcome = yield
Expand All @@ -187,33 +182,66 @@ def pytest_runtest_makereport(item):
xfail = hasattr(report, 'wasxfail')
if (report.skipped and xfail) or (report.failed and not xfail):
print("Test failed - handling it")
file_name = "latest_logs/" + report.nodeid.replace("::", "_") + ".png"

project_root = os.path.abspath(os.path.dirname(__file__))
error_logs_dir = os.path.join(project_root, "latest_logs", "errors")
os.makedirs(error_logs_dir, exist_ok=True)

test_name = report.nodeid.replace("::", "_").split("/")[-1]
file_name = os.path.join(error_logs_dir, test_name + ".png")
print(f"Intended screenshot path: {file_name}")

browser = None
if hasattr(item, "cls"):
browser = getattr(item.cls, "browser", None)
if not browser:
browser = getattr(item, "_browser", None)
print(f"Browser found in item attribute")

if browser:
print("Browser object found - making screenshot")
_capture_screenshot(file_name, browser)
if file_name:
html = '<div><img src="%s" alt="screenshot" style="width:304px;height:228px;" ' \
'onclick="window.open(this.src)" align="right"/></div>' % file_name
extra.append(pytest_html.extras.html(html))
try:
print("Browser object found - making screenshot")
_capture_screenshot(file_name, browser)
if os.path.exists(file_name):
print(f"Screenshot successfully saved at: {file_name}")
html = ('<div><img src="%s" alt="screenshot" '
'style="width:304px;height:228px;" onclick="window.open(this.src)" '
'align="right"/></div>') % os.path.relpath(file_name)
extra.append(pytest_html.extras.html(html))
else:
print(f"Screenshot not found at: {file_name}")
except Exception as e:
print(f"Exception occurred while capturing screenshot: {e}")
else:
print("No browser object found - skipping screenshot capture")

report.extra = extra


def _capture_screenshot(name, browser):
project_root = os.path.abspath(os.path.dirname(__file__))
logs_dir = os.path.join(project_root, "latest_logs")
os.makedirs(logs_dir, exist_ok=True)
file_path = os.path.join(logs_dir, name)
browser.get_full_page_screenshot_as_file(file_path)
"""
Helper function to capture and save a screenshot.

- Ensures the target directory exists.
- Uses the browser object to capture a full-page screenshot.
:param name: The full path where the screenshot will be saved.
:param browser: The browser object used for screenshot capture.
"""
try:
print(f"Creating error directory at:{os.path.dirname(name)}")
os.makedirs(os.path.dirname(name), exist_ok=True)
print(f"Saving screenshot to: {name}")
# browser.get_full_page_screenshot_as_file(file_path)
browser.get_full_page_screenshot_as_file(name)
print(f"Screenshot captured: {name}")
except Exception as e:
print(f"Failed to capture screenshot '{name}': {e}")


# Hook to customize the HTML report table row cells
def pytest_html_results_table_row(report, cells):
"""Styling for html.report"""
"""Styling for html report
Hook to customize the HTML report table row cells
"""
if report.failed:
cells.insert(1, ("✘", "fail"))
else:
Expand All @@ -222,17 +250,19 @@ def pytest_html_results_table_row(report, cells):

def pytest_sessionstart(session):
""" Hook to delete previous allure reports before running the tests"""
project_root = os.path.abspath(os.path.dirname(__file__))
folder_path = os.path.join(project_root, "allure_reports")
if os.path.exists(folder_path) and os.listdir(folder_path):
for root, dirs, files in os.walk(folder_path, topdown=False):
for file in files:
os.remove(os.path.join(root, file))
for dir in dirs:
os.rmdir(os.path.join(root, dir))
try:
project_root = os.path.abspath(os.path.dirname(__file__))
folder_path = os.path.join(project_root, "allure_reports")
if os.path.exists(folder_path) and os.listdir(folder_path):
for root, dirs, files in os.walk(folder_path, topdown=False):
for file in files:
os.remove(os.path.join(root, file))
for dir in dirs:
os.rmdir(os.path.join(root, dir))
except Exception as e:
print(f"Failed to clear allure reports: {e}")


# Command-line options
def pytest_addoption(parser):
parser.addoption(
"--browser-name",
Expand Down Expand Up @@ -321,6 +351,7 @@ def make_full_screenshot(browser, savename):

@pytest.fixture(scope="session", autouse=True)
def check_skip_condition():
""" Skips a test file from running"""
import os
if os.getenv("SKIP_MODULES") == "1":
pytest.skip("Skipping tests due to global configuration.", allow_module_level=True)
pytest.skip("Skipping tests due to global configuration.", allow_module_level=True)
12 changes: 6 additions & 6 deletions locators/explore_ephys_locators.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ class ExploreEphysLocators:
"Measurements']")
DV_OVERVIEW = (By.XPATH, "//span[contains(text(),' Overview')]")
DV_REG_DATE = (By.XPATH, "//div[@class='uppercase text-neutral-4' and text()='Registration "
"Date']/following-sibling::div[@class='mt-2']")
"date']/following-sibling::div[@class='mt-2']")
DV_REG_DATE_TITLE = (By.XPATH, "//div[@class='uppercase text-neutral-4' and text("
")='Registration Date']")
")='Registration date']")
DV_SPECIES = (By.XPATH, "//div[@class='uppercase text-neutral-4' and text("
")='Species']/following-sibling::div[@class='mt-2']")
DV_SPECIES_TITLE = (By.XPATH, "//div[@class='uppercase text-neutral-4' and text()='Species']")
Expand All @@ -58,22 +58,22 @@ class ExploreEphysLocators:
"'Electrophysiology')]")
FILTERED_ETYPE = (By.XPATH, "//td[@class='ant-table-cell text-primary-7 cursor-pointer "
"before:!content-none ant-table-cell-ellipsis' and @title='bNAC']")
FILTER_ETYPE_BTN = (By.XPATH, "//div[@class='flex items-center gap-3 ']//span[text()='E-Type']")
FILTER_ETYPE_BTN = (By.XPATH, "//div[@class='flex items-center gap-3 ']//span[text()='E-type']")
FILTER_ETYPE_SEARCH_INPUT = (By.XPATH, "(//input[@class='ant-select-selection-search-input"
"'])[2]")
FILTER_ETYPE_INPUT_TYPE_AREA = (By.XPATH, "//div[@class='ant-select-selection-search']")
FILTER_ETYPE_SEARCH = (By.XPATH, "//div[@class='ant-select-selection-overflow']")
LOAD_MORE_BUTTON = (By.XPATH, "//button[@type='button' and text()='Load 30 more results...']")
LV_GRID_VIEW = (By.XPATH, "//div[@data-testid='explore-section-listing-view']")
LV_BRAIN_REGION = (By.XPATH, "//span[@class='ant-table-column-title']//div[text()='Brain "
"Region']")
"region']")
LV_CONTRIBUTORS = (By.XPATH, "//th[@data-testid='column-header']//div[text()='Contributors']")
LV_ETYPE = (By.XPATH, "//th[@data-testid='column-header']//div[text()='E-Type']")
LV_ETYPE = (By.XPATH, "//th[@data-testid='column-header']//div[text()='E-type']")
LV_FILTER_APPLY_BTN = (By.XPATH, "//button[@type='submit' and text()='Apply']")
LV_FILTER_BTN = (By.XPATH, "//button[@type='button' and "
"@aria-label='listing-view-filter-button']")
LV_FILTER_CLOSE_BTN = (By.XPATH, "//button[@type='button' and @aria-label='Close']")
LV_FILTER_MTYPE = (By.XPATH, "//span[text()='M-Type']")
LV_FILTER_MTYPE = (By.XPATH, "//span[text()='M-type']")
LV_NAME = (By.XPATH, "//th[@data-testid='column-header']//div[text()='Name']")
LV_PREVIEW = (By.XPATH, "//th[@data-testid='column-header']//div[text()='Preview']")
LV_REGISTRATION_DATE = (By.XPATH, "//th[@data-testid='column-header']//div[text("
Expand Down
14 changes: 7 additions & 7 deletions locators/explore_morphology_locators.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,18 @@ class ExploreMorphologyPageLocators:
FILTER_PANEL = (By.XPATH, "//div[@data-testid='listing-view-filter-panel']")
FIRST_ROW = (By.XPATH, "//tbody[@class='ant-table-tbody']/tr[2]")
LV_BRAIN_REGION = (By.XPATH, "//span[@class='ant-table-column-title']//div[text()='Brain "
"Region']")
"region']")
LV_CHECKBOX = (By.XPATH, "")
LV_CONTRIBUTORS = (By.XPATH, "//th[@data-testid='column-header']//div[text()='Contributors']")
LV_FILTER_APPLY_BTN = (By.XPATH, "//button[@type='submit' and text()='Apply']")
LV_FILTER_MTYPE = (By.XPATH, "//span[text()='M-Type']")
LV_MTYPE = (By.XPATH, "//th[@data-testid='column-header']//div[text()='M-Type']")
LV_FILTER_MTYPE = (By.XPATH, "//span[text()='M-type']")
LV_MTYPE = (By.XPATH, "//th[@data-testid='column-header']//div[text()='M-type']")
LV_NAME = (By.XPATH, "//th[@data-testid='column-header']//div[text()='Name']")
LV_PREVIEW = (By.XPATH, "//th[@data-testid='column-header']//div[text()='Preview']")
# LV_REGISTRATION_DATE = (By.XPATH, "//th[@data-testid='column-header']//div[text("
# ")='Registration date']")
LV_REGISTRATION_DATE = (By.XPATH, "//span[@class='ant-table-column-title']//div[text("
")='Creation Date']")
LV_REGISTRATION_DATE = (By.XPATH, "//th[@data-testid='column-header']//div[text("
")='Registration date']")
# LV_REGISTRATION_DATE = (By.XPATH, "//span[@class='ant-table-column-title']//div[text("
# ")='Creation Date']")
LV_SPECIES = (By.XPATH, "//th[@data-testid='column-header']//div[text()='Species']")
# LV_THUMBNAIL = (By.XPATH, "//img[starts-with(@alt,'Morphology preview')]")
LV_THUMBNAIL = (By.XPATH, "//img[@alt='img preview']")
Expand Down
2 changes: 1 addition & 1 deletion locators/explore_page_locators.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ExplorePageLocators:
"font-light']")
BRAIN_REGION_PANEL = (By.XPATH, "//span[text()='Brain region']")
BRP_CEREBRUM = (By.XPATH, "//span[@title='Cerebrum' and text()='Cerebrum']")
CEREBRAL_CORTEX_TITLE = (By.XPATH, "//span[@title='Cerebral Cortex']")
CEREBRAL_CORTEX_TITLE = (By.XPATH, "//span[@title='Cerebral cortex']")
CEREBRUM_BTN = (By.XPATH, "(//button[@type='button' and @aria-expanded='false'])[3]")
COUNT_SWITCH = (By.CSS_SELECTOR, "button[type='button'][role='switch'][aria-checked='false']")
EXPERIMENTAL_DATA_BTN = (By.XPATH, "//button[text()='Experimental data']")
Expand Down
Loading