Skip to content

Commit 00c5fe2

Browse files
author
Gaurav Singh
committed
Chapter 9: Visual validation of pdf files
Change log: 1. Added a test to generate a pdf and visually assert it 2. Basic base page lib with wrappers over selenium functions 3. Page objects for app.invoicesimple.com 4. validate_pdf method in eyes_manager.py 5. file utils to check if file is present, remove if it exists and move to required dir 6. util to execute command from python 7. generic wait method which can accept a function and then execute it till a certain timeout is reached.
1 parent 5ab4cb4 commit 00c5fe2

File tree

11 files changed

+212
-0
lines changed

11 files changed

+212
-0
lines changed

automation/core/eyes_manager.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
1+
import os
2+
13
from applitools.common import BatchInfo
24
from applitools.selenium import Eyes
35

46
from automation.config.base import APPLITOOLS_API_KEY
7+
from automation.core.helper import get_resources_dir_path
8+
from automation.core.io import execute_cmd
9+
10+
IMAGE_TESTER_PATH = "{}/libs/ImageTester_0_4_8.jar".format(
11+
os.environ.get('HOME'))
512

613

714
class EyesManager:
@@ -36,6 +43,18 @@ def validate_element(self, element, tag=None):
3643
def validate_frame(self, frame_reference, region, tag=None):
3744
self.eyes.check_region_in_frame(frame_reference, region, tag=tag)
3845

46+
@staticmethod
47+
def validate_pdf():
48+
cmd = """java -jar {} -k {} -f {}""".format(IMAGE_TESTER_PATH,
49+
APPLITOOLS_API_KEY,
50+
get_resources_dir_path())
51+
52+
output, _ = execute_cmd(cmd)
53+
str_output = output.decode('utf-8')
54+
55+
print('Command execution completed... \n' + str_output)
56+
return str_output
57+
3958
def open_eyes(self, test_name):
4059
self.eyes.open(self.driver, self.app_name,
4160
test_name=test_name)

automation/core/file_utils.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import os
2+
3+
4+
def is_file_downloaded(path):
5+
if os.path.exists(path):
6+
return True
7+
8+
9+
def remove_file_if_exists(path):
10+
if os.path.exists(path):
11+
os.remove(path)
12+
13+
14+
def move_file_to_path(src, dst):
15+
os.rename(src, dst)

automation/core/helper.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from pathlib import Path
2+
3+
4+
def get_resources_dir_path():
5+
return str(Path(__file__).parent.parent.resolve()) + '/resources'
6+

automation/core/io.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import subprocess
2+
from subprocess import Popen
3+
4+
5+
def execute_cmd(cmd):
6+
handle = Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
7+
shell=True)
8+
stdout, stderr = handle.communicate()
9+
return stdout, stderr

automation/core/wait.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import time
2+
3+
POLL_FREQUENCY = 0.5
4+
WAIT_TIME = 1
5+
6+
7+
def until(method, args=None, timeout=30, message=''):
8+
time_to_wait = WAIT_TIME
9+
10+
end_time = time.time() + timeout
11+
while True:
12+
try:
13+
value = method(args)
14+
if value:
15+
return value
16+
except Exception as exc:
17+
print(exc)
18+
19+
time_to_wait *= POLL_FREQUENCY
20+
21+
time.sleep(time_to_wait)
22+
if time.time() > end_time:
23+
break
24+
raise NameError(message)

automation/page_objects/base_page.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import selenium.webdriver.support.expected_conditions as ec
2+
from selenium.webdriver.support.wait import WebDriverWait
3+
4+
5+
class BasePage:
6+
def __init__(self, driver):
7+
self.driver = driver
8+
9+
def get_visible_element(self, locator, timeout=30):
10+
return WebDriverWait(self.driver, timeout).until(
11+
ec.visibility_of_element_located(locator))
12+
13+
@staticmethod
14+
def enter_text(element, text):
15+
element.send_keys(text)
16+
17+
@staticmethod
18+
def click(element):
19+
element.click()
20+
21+
def switch_to_window(self, index=1):
22+
handles = self.driver.window_handles
23+
24+
if len(handles) == 1:
25+
WebDriverWait(self.driver, 30).until(self.open_windows_gt_one)
26+
27+
handles = self.driver.window_handles
28+
self.driver.switch_to.window(handles[index])
29+
30+
@staticmethod
31+
def open_windows_gt_one(driver):
32+
return len(driver.window_handles) > 1

automation/page_objects/invoice_simple/__init__.py

Whitespace-only changes.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from pathlib import Path
2+
3+
from selenium.webdriver.common.by import By
4+
5+
from automation.core.file_utils import *
6+
from automation.core.helper import get_resources_dir_path
7+
from automation.core.wait import until
8+
from automation.page_objects.base_page import BasePage
9+
10+
DOWNLOAD_PATH = '{}/Downloads'.format(str(Path.home()))
11+
12+
13+
class InvoiceDownloadPage(BasePage):
14+
DOWNLOAD_PDF = (By.XPATH, '//a[contains(text(), "PDF")]')
15+
16+
def __init__(self, driver):
17+
super().__init__(driver)
18+
self.downloaded_file_path = None
19+
self.pdf_file_name = None
20+
21+
def download_pdf(self, file_name):
22+
self.pdf_file_name = '{}.pdf'.format(file_name)
23+
self.downloaded_file_path = '{}/{}'.format(DOWNLOAD_PATH,
24+
self.pdf_file_name)
25+
26+
self.switch_to_window()
27+
remove_file_if_exists(self.downloaded_file_path)
28+
29+
self.click(self.get_visible_element(self.DOWNLOAD_PDF))
30+
self.wait_till_pdf_download(self.downloaded_file_path)
31+
32+
return self
33+
34+
@staticmethod
35+
def wait_till_pdf_download(path):
36+
until(method=is_file_downloaded, args=path)
37+
38+
def move_to_resources(self):
39+
src = self.downloaded_file_path
40+
dst = '{}/{}'.format(get_resources_dir_path(), self.pdf_file_name)
41+
move_file_to_path(src, dst)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from selenium.webdriver.common.by import By
2+
3+
from automation.page_objects.base_page import BasePage
4+
from automation.page_objects.invoice_simple.invoice_download_page import \
5+
InvoiceDownloadPage
6+
7+
8+
class InvoicePage(BasePage):
9+
FROM_NAME = (By.ID, 'invoice-company-name')
10+
TO_NAME = (By.ID, 'invoice-client-name')
11+
ITEM_DESCRIPTION = (By.ID, 'invoice-item-code')
12+
ITEM_RATE = (By.CSS_SELECTOR, 'td[data-label="Price"] input')
13+
GET_LINK = (By.CSS_SELECTOR, '.invoice-detail-about button')
14+
15+
def __init__(self, driver):
16+
super().__init__(driver)
17+
18+
def enter_from_and_to_details(self, from_name, to_name):
19+
sender_name = self.get_visible_element(self.FROM_NAME)
20+
self.enter_text(sender_name, from_name)
21+
22+
receiver_name = self.get_visible_element(self.TO_NAME)
23+
self.enter_text(receiver_name, to_name)
24+
return self
25+
26+
def enter_item_with_rate(self, item, rate):
27+
item_description = self.get_visible_element(self.ITEM_DESCRIPTION)
28+
self.enter_text(item_description, item)
29+
30+
item_rate = self.get_visible_element(self.ITEM_RATE)
31+
self.enter_text(item_rate, rate)
32+
return self
33+
34+
def click_on_get_link(self):
35+
get_link_btn = self.get_visible_element(self.GET_LINK)
36+
self.click(get_link_btn)
37+
return InvoiceDownloadPage(self.driver)

automation/tests/chapter_09/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)