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
23 changes: 23 additions & 0 deletions .github/workflows/pylint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Pylint

on: [push]

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pylint
- name: Analyzing the code with pylint
run: |
pylint **/*.py
150 changes: 150 additions & 0 deletions reports/API_And_WEB_Testing

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions run_tests.bat
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ set dir=%CD%
set report_dir=%CD%\reports
set test_dir=%CD%\tests

set browser="Headless Chrome"
set browser=Chrome

echo The test directory is %test_dir%

python -m pytest -s -vv --gherkin-terminal-reporter %test_dir%\step_defs --html=%report_dir%\report.html -n 4 --capture sys --browser %browser%
python -m pytest -s -vv --gherkin-terminal-reporter %test_dir%\step_defs --html=%report_dir%\report.html -n 4 --capture=tee-sys --Browser="%browser%" --full-trace

Pause
pause
1 change: 0 additions & 1 deletion tests/features/add_task.feature
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# Created by Admin at 16/10/2022
Feature: Add task

Scenario Outline: Add New Task Successfully
Expand Down
151 changes: 132 additions & 19 deletions tests/pages/base_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,37 @@
from utilities.settings import SCREENSHOT_PATH
from selenium.webdriver.chrome.options import Options


headless_options = Options()
headless_options.add_argument("--headless")


class WebBrowser:

def __init__(self, browser, implicit_wait=3, screenshot_path=SCREENSHOT_PATH ):
"""
Class representing a web browser instance.
"""

def __init__(self, browser: str, implicit_wait: int = 3, screenshot_path: str = SCREENSHOT_PATH):
"""
Initialize the WebBrowser instance.

Args:
browser (str): The browser to use.
implicit_wait (int): The implicit wait time.
screenshot_path (str): The path to save screenshots.
"""
self.driver = self.initialize_browser(browser)
self.implicit_wait = implicit_wait
self.screenshot_path = screenshot_path

def initialize_browser(self, browser):
# Initialize the WebDriver instance
def initialize_browser(self, browser: str) -> webdriver:
"""
Initialize the WebDriver instance.

Args:
browser (str): The browser to initialize.

Returns:
webdriver: The WebDriver instance.
"""
if browser == 'Chrome':
return webdriver.Chrome()
elif browser == 'Edge':
Expand All @@ -32,43 +49,139 @@ def initialize_browser(self, browser):
else:
raise Exception(f'Browser "{browser}" is not supported')

def open_browser(self, url):
def open_browser(self, url: str) -> None:
"""
Open the browser and navigate to the given URL.

Args:
url (str): The URL to navigate to.

Returns:
None
"""
self.driver.get(url)
self.driver.maximize_window()

def close_browser(self):
def close_browser(self) -> None:
"""
Close the browser.

Returns:
None
"""
self.driver.quit()

def get_element(self, by_locator):
def get_element(self, by_locator: tuple):
"""
Get the web element identified by the locator.

Args:
by_locator (tuple): The locator strategy and value.

Returns:
web element: The web element.
"""
return WebDriverWait(self.driver, self.implicit_wait).until(EC.visibility_of_element_located(by_locator))

def get_element_text(self, by_locator):
def get_element_text(self, by_locator: tuple) -> str:
"""
Get the text of the web element identified by the locator.

Args:
by_locator (tuple): The locator strategy and value.

Returns:
str: The text of the web element.
"""
return self.get_element(by_locator).text

def type_element(self, by_locator, text):
def type_element(self, by_locator: tuple, text: str) -> None:
"""
Type text into the web element identified by the locator.

Args:
by_locator (tuple): The locator strategy and value.
text (str): The text to type into the web element.

Returns:
None
"""
self.get_element(by_locator).send_keys(text)

def click_element(self, by_locator):
def click_element(self, by_locator: tuple) -> None:
"""
Click on the web element identified by the locator.

Args:
by_locator (tuple): The locator strategy and value.

Returns:
None
"""
self.get_element(by_locator).click()

def send_keys(self, by_locator, key):
def send_keys(self, by_locator: tuple, key) -> None:
"""
Send keys to the web element identified by the locator.

Args:
by_locator (tuple): The locator strategy and value.
key: The keys to send.

Returns:
None
"""
self.get_element(by_locator).send_keys(key)

def is_element_visible(self, by_locator):
def is_element_visible(self, by_locator: tuple) -> bool:
"""
Check if the web element identified by the locator is visible.

Args:
by_locator (tuple): The locator strategy and value.

Returns:
bool: True if the element is visible, False otherwise.
"""
return self.get_element(by_locator).is_displayed()

def check_if_element_exists(self, by_locator):
def check_if_element_exists(self, by_locator: tuple) -> bool:
"""
Check if the web element identified by the locator exists.

Args:
by_locator (tuple): The locator strategy and value.

Returns:
bool: True if the element exists, False otherwise.
"""
try:
self.driver.find_element(*by_locator)
return True

# NoSuchElementException thrown if not present
except NoSuchElementException:
return False

def find_elements(self, by_locator):
def find_elements(self, by_locator: tuple):
"""
Find all web elements identified by the locator.

Args:
by_locator (tuple): The locator strategy and value.

Returns:
list: List of web elements.
"""
return self.driver.find_elements(*by_locator)

def take_screenshot(self, name):
# take screenshot
def take_screenshot(self, name: str) -> None:
"""
Take a screenshot and save it with the given name.

Args:
name (str): The name to save the screenshot.

Returns:
None
"""
self.driver.save_screenshot(self.screenshot_path + name + '.png')
83 changes: 66 additions & 17 deletions tests/pages/todo_list_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,38 @@
from selenium.webdriver.common.keys import Keys

class ToDoListLocators:
todo_list_url = 'http://webdriveruniversity.com/To-Do-List/index.html'
title = 'WebDriver | To Do List'
input_element = (By.XPATH, '//input[@placeholder="Add new todo" and not(@style="display: none;")]')
tasks_list = (By.TAG_NAME, 'li')
plus_icon = (By.ID, 'plus-icon')

todo_list_url: str = 'http://webdriveruniversity.com/To-Do-List/index.html'
title: str = 'WebDriver | To Do List'
input_element: tuple = (By.XPATH, '//input[@placeholder="Add new todo" and not(@style="display: none;")]')
tasks_list: tuple = (By.TAG_NAME, 'li')
plus_icon: tuple = (By.ID, 'plus-icon')

class ToDOList(WebBrowser):
"""
Class representing the ToDoList page.
"""

def open_page(self):
def open_page(self) -> None:
"""
Open the ToDoList page and verify the title.

Returns:
None
"""
self.open_browser(ToDoListLocators.todo_list_url)
assert self.driver.title == ToDoListLocators.title

def validate_if_task_exist(self, task_name):
def validate_if_task_exist(self, task_name: str) -> bool:
"""
Validate if a task exists in the tasks list.

Args:
task_name (str): The name of the task to validate.

task_exist_flag = False
Returns:
bool: True if the task exists, False otherwise.
"""
task_exist_flag: bool = False
tasks_list_elements = self.find_elements(ToDoListLocators.tasks_list)
for task in tasks_list_elements:
if task.text != task_name:
Expand All @@ -28,38 +43,72 @@ def validate_if_task_exist(self, task_name):

return task_exist_flag

def validate_if_task_marked(self, task_name):
def validate_if_task_marked(self, task_name: str) -> bool:
"""
Validate if a task is marked as completed.

Args:
task_name (str): The name of the task to validate.

Returns:
bool: True if the task is marked as completed, False otherwise.
"""
locator = (By.XPATH, f'//li[text()="{task_name}" and @class="completed"]')
return self.check_if_element_exists(locator)

def add_new_task(self, task_name):
def add_new_task(self, task_name: str) -> None:
"""
Add a new task to the ToDoList.

Args:
task_name (str): The name of the task to add.

# validate in input field is visible
Returns:
None
"""
if self.check_if_element_exists(ToDoListLocators.input_element) is False:
self.click_element(ToDoListLocators.plus_icon)

self.type_element(ToDoListLocators.input_element, task_name)
self.send_keys(ToDoListLocators.input_element, Keys.ENTER)

#take screenshot
self.take_screenshot(f'{task_name}_task_added')

def mark_task_as_completed(self, task_name: str) -> None:
"""
Mark a task as completed.

def mark_task_as_completed(self, task_name):
Args:
task_name (str): The name of the task to mark as completed.

Returns:
None
"""
locator = (By.XPATH, f'//li[text()="{task_name}"]')
self.click_element(locator)

def unmark_task_as_completed(self, task_name: str) -> None:
"""
Unmark a completed task.

def unmark_task_as_completed(self, task_name):
Args:
task_name (str): The name of the task to unmark.

Returns:
None
"""
locator = (By.XPATH, f'//li[text()="{task_name}" and @class="completed"]')
#COLOCAR TRATAMENTO DE ERRO AQUI
self.click_element(locator)

def delete_task(self, task_name: str) -> None:
"""
Delete a task from the ToDoList.

def delete_task(self, task_name):
Args:
task_name (str): The name of the task to delete.

Returns:
None
"""
locator = (By.XPATH, f'//li[text()="{task_name}"]/span')
self.click_element(locator)
Loading