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

Release - v1 #1

Merged
merged 80 commits into from
Aug 3, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
0566e85
feat - new elements abstractions
jjpaulo2 Jul 16, 2024
b1afd11
feat - table abstraction
jjpaulo2 Jul 16, 2024
78f0f9b
fix - getting td and th for each row
jjpaulo2 Jul 16, 2024
f00deb4
feat - table printing
jjpaulo2 Jul 18, 2024
ed86723
feat - screenshot abstraction
jjpaulo2 Jul 18, 2024
b3e23e7
refact - simplify code
jjpaulo2 Jul 18, 2024
d912768
fix - getting complete page screenshot
jjpaulo2 Jul 18, 2024
e83ef2d
feat - cookies abstraction
jjpaulo2 Jul 19, 2024
cb7b3c1
refact - source and tag
jjpaulo2 Jul 19, 2024
4499f87
feat - adding many elements reading
jjpaulo2 Jul 19, 2024
4ac754d
feat - link methods in button element
jjpaulo2 Jul 19, 2024
38fc702
feat - starter new readme content
jjpaulo2 Jul 19, 2024
adeb279
fix - better readme formatting
jjpaulo2 Jul 19, 2024
207f236
feat - screenshot examples
jjpaulo2 Jul 19, 2024
1e3cfee
fix - sumary identation
jjpaulo2 Jul 19, 2024
de7a019
feat - moving print table to commons
jjpaulo2 Jul 19, 2024
c079c14
feat - new formatting
jjpaulo2 Jul 19, 2024
56b141e
style - new line length
jjpaulo2 Jul 19, 2024
208fbbd
feat - starter elements documentation
jjpaulo2 Jul 19, 2024
794495c
fix - readme typing errors
jjpaulo2 Jul 19, 2024
e227c06
feat - generical keyboard
jjpaulo2 Jul 21, 2024
e2af27f
feat - improvements in timer class
jjpaulo2 Jul 21, 2024
8558896
feat - take just screenshot bytes content
jjpaulo2 Jul 21, 2024
d4e5f0c
feat - javascript console abstraction
jjpaulo2 Jul 21, 2024
3b00475
feat - method to delete cookie
jjpaulo2 Jul 21, 2024
fc45e1e
feat - read inline css values for element
jjpaulo2 Jul 21, 2024
3e62ea4
feat - real time element values
jjpaulo2 Jul 22, 2024
16d3d83
feat - keyboard shortcut
jjpaulo2 Jul 22, 2024
c995fe1
feat - new elements documentation
jjpaulo2 Jul 26, 2024
d89ff90
feat - add table print to doc
jjpaulo2 Jul 26, 2024
6d9c580
feat - add form attributes
jjpaulo2 Jul 26, 2024
89c9b67
feat - tabs abstraction
jjpaulo2 Jul 26, 2024
e07428f
Merge branch 'main' into release/v1
jjpaulo2 Jul 26, 2024
578d918
feat - xpath utils
jjpaulo2 Jul 26, 2024
e4d239d
feat - new wait interface
jjpaulo2 Jul 29, 2024
a76b767
refact - get elements on-demand
jjpaulo2 Jul 29, 2024
a2698f7
fix - elements factory
jjpaulo2 Jul 29, 2024
6d77c23
feat - ensure_element decorator
jjpaulo2 Jul 29, 2024
a3fc34d
fix - remove time import
jjpaulo2 Jul 29, 2024
ff82dd5
refact - removing TIMEOUT const
jjpaulo2 Jul 29, 2024
c524ea4
feat - print lists and selects
jjpaulo2 Jul 29, 2024
56862c4
feat - tests from xpath module
jjpaulo2 Jul 29, 2024
88e9279
feat - file abstraction
jjpaulo2 Jul 29, 2024
90cadac
feat - updating readme
jjpaulo2 Jul 30, 2024
0e07930
style - formatting for exceptions
jjpaulo2 Jul 30, 2024
d1c855d
syle - formatting form
jjpaulo2 Jul 30, 2024
6d3f17a
fix - readme typo
jjpaulo2 Jul 30, 2024
5dead4a
feat - new docs with mkdocs
jjpaulo2 Aug 1, 2024
0264316
feat - running tests on pull request
jjpaulo2 Aug 1, 2024
02160bf
feat - allow python >= 3.9
jjpaulo2 Aug 1, 2024
f6c8111
fix - install dependencies on pipeline
jjpaulo2 Aug 1, 2024
c40e4b2
fix - allow python >= 3.10
jjpaulo2 Aug 1, 2024
9ac2798
fix - temp security issue
jjpaulo2 Aug 1, 2024
a0ed279
fix - removing tests from check command
jjpaulo2 Aug 1, 2024
7005dff
feat - rewrite elements docs
jjpaulo2 Aug 1, 2024
5e429ae
fix - code formatting
jjpaulo2 Aug 1, 2024
ee7d4a9
docs - sponsor badge
jjpaulo2 Aug 1, 2024
5198025
docs - new interactions pages
jjpaulo2 Aug 1, 2024
e415224
docs - fix typing
jjpaulo2 Aug 1, 2024
f9263f7
docs - configure docs auto build
jjpaulo2 Aug 2, 2024
ae040f2
feat - publish action
jjpaulo2 Aug 2, 2024
ffc2575
docs - new social cards
jjpaulo2 Aug 2, 2024
0b5cce7
docs - low level documentation
jjpaulo2 Aug 2, 2024
7fc5780
chore - new fastrpa object unit tests
jjpaulo2 Aug 2, 2024
64ebeaa
chore - fastrpa class tests
jjpaulo2 Aug 2, 2024
2dd57c6
docs - fix typo
jjpaulo2 Aug 2, 2024
525242a
doc - fix link
jjpaulo2 Aug 2, 2024
66e4d70
doc - install instructions
jjpaulo2 Aug 2, 2024
03ed7e2
refact - rename workflow file
jjpaulo2 Aug 2, 2024
3f521b3
chore - adding docs link in pyproject toml
jjpaulo2 Aug 2, 2024
7084f7d
feat - radio and checkbox elements
jjpaulo2 Aug 3, 2024
03069cf
chore - also build the docs on tests
jjpaulo2 Aug 3, 2024
5c11582
docs - adding checkbox and radio elements
jjpaulo2 Aug 3, 2024
e51b06e
chore - adding new utils tests
jjpaulo2 Aug 3, 2024
53903d6
style - aplicando ruff
jjpaulo2 Aug 3, 2024
a70089b
chore - adding html method
jjpaulo2 Aug 3, 2024
dd9ba41
Merge branch 'main' into release/v1
jjpaulo2 Aug 3, 2024
b51fefe
release v1.0.0
jjpaulo2 Aug 3, 2024
db3e122
style - applying ruff
jjpaulo2 Aug 3, 2024
7b25c61
docs - improve reading
jjpaulo2 Aug 3, 2024
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
11 changes: 5 additions & 6 deletions fastrpa/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
from fastrpa.app import FastRPA, Web
from fastrpa.elements.form import Form
from fastrpa.exceptions import ElementNotFound
from fastrpa.exceptions import ElementNotFound, ElementNotFoundAfterTime


__all__ = (
"FastRPA",
"Web",
"Form",
"ElementNotFound",
'FastRPA',
'Web',
'ElementNotFound',
'ElementNotFoundAfterTime',
)
71 changes: 36 additions & 35 deletions fastrpa/app.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
from time import sleep
from selenium.webdriver import Remote, ChromeOptions, ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver import Remote, ChromeOptions
from fastrpa.commons import (
get_element_text,
get_browser_options,
wait_until_element_is_hidden,
wait_until_element_is_present,
VISIBILITY_TIMEOUT,
)
from fastrpa.elements.form import Form
from fastrpa.settings import VISIBILITY_TIMEOUT
from fastrpa.core.elements import Element

from fastrpa.core.timer import Timer
from fastrpa.core.keyboard import Keyboard
from fastrpa.factories import ElementFactory
from fastrpa.types import BrowserOptions, BrowserOptionsClass, WebDriver


Expand All @@ -19,44 +18,46 @@ def __init__(
webdriver: WebDriver,
visibility_timeout: int,
):
self.url = url
self._keyboard: Keyboard | None = None
self._timer: Timer | None = None
self.starter_url = url
self.webdriver = webdriver
self.webdriver.get(url)
self.webdriver.get(self.starter_url)
self._element_factory = ElementFactory(self.webdriver)
self.visibility_timeout = visibility_timeout

def reset(self):
self.webdriver.get(self.url)

def form(self, xpath: str) -> Form:
return Form(xpath, self.webdriver, self.visibility_timeout)

def read(self, xpath: str) -> str | None:
return get_element_text(self.webdriver, xpath, self.visibility_timeout)

def has_content(self, value: str) -> bool:
return value in self.webdriver.page_source

def wait_until_hide(self, xpath: str):
wait_until_element_is_hidden(self.webdriver, xpath)
@property
def url(self) -> str:
return self.webdriver.current_url

def wait_until_present(self, xpath: str):
wait_until_element_is_present(self.webdriver, xpath)
@property
def keyboard(self) -> Keyboard:
if self._keyboard:
return self._keyboard
self._keyboard = Keyboard(self.webdriver)
return self._keyboard

def wait_seconds(self, seconds: int):
sleep(seconds)
@property
def timer(self) -> Timer:
if self._timer:
return self._timer
self._timer = Timer(self.webdriver)
return self._timer

def press_esc(self):
ActionChains(self.webdriver).send_keys(Keys.ESCAPE).perform()
def reset(self):
self.webdriver.get(self.starter_url)

def press_enter(self):
ActionChains(self.webdriver).send_keys(Keys.ENTER).perform()
def element(self, xpath: str, wait: bool = True) -> Element:
jjpaulo2 marked this conversation as resolved.
Show resolved Hide resolved
if not wait:
return self._element_factory.get(xpath)
return self._element_factory.get_when_available(xpath, self.visibility_timeout)

def press_tab(self):
ActionChains(self.webdriver).send_keys(Keys.TAB).perform()
def has_content(self, value: str) -> bool:
return value in self.webdriver.page_source


class FastRPA:
browser_arguments = ["--start-maximized", "--ignore-certificate-errors"]
browser_arguments = ['--start-maximized', '--ignore-certificate-errors']

def __init__(
self,
Expand Down
54 changes: 4 additions & 50 deletions fastrpa/commons.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
from selenium.webdriver import ChromeOptions
from selenium.common.exceptions import TimeoutException, ElementNotInteractableException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support.ui import Select

import os
import requests
import mimetypes

from fastrpa.exceptions import ElementNotFound
from fastrpa.settings import HIDDEN_TIMEOUT
from fastrpa.types import BrowserOptions, BrowserOptionsClass, WebDriver


VISIBILITY_TIMEOUT = 10
HIDDEN_TIMEOUT = 60


def get_browser_options(
options: list[str], options_class: BrowserOptionsClass = ChromeOptions
) -> BrowserOptions:
Expand All @@ -27,25 +21,6 @@ def get_browser_options(
return instance


def get_element(
webdriver_or_parent_node: WebDriver | WebElement,
xpath: str,
timeout: int = VISIBILITY_TIMEOUT,
) -> WebElement:
try:
return WebDriverWait(webdriver_or_parent_node, timeout).until(
expected_conditions.presence_of_element_located((By.XPATH, xpath))
)

except ElementNotInteractableException:
return WebDriverWait(webdriver_or_parent_node, timeout).until(
expected_conditions.element_to_be_clickable((By.XPATH, xpath))
)

except TimeoutException:
raise ElementNotFound(xpath, timeout)


def wait_until_element_is_hidden(
webdriver_or_parent_node: WebDriver | WebElement,
xpath: str,
Expand All @@ -66,37 +41,16 @@ def wait_until_element_is_present(
)


def get_select_element(
webdriver_or_parent_node: WebDriver | WebElement,
xpath: str,
timeout: int = VISIBILITY_TIMEOUT,
) -> Select:
return Select(get_element(webdriver_or_parent_node, xpath, timeout))


def get_element_text(
webdriver_or_parent_node: WebDriver | WebElement,
xpath: str,
timeout: int = VISIBILITY_TIMEOUT,
) -> str | None:
element = get_element(webdriver_or_parent_node, xpath, timeout)
if element.text:
return element.text
elif value := element.get_attribute("value"):
return value
return None


def get_file_path(path: str) -> str:
if os.path.isfile(path):
return path

file_response = requests.get(path)
file_extension = mimetypes.guess_extension(file_response.headers["Content-Type"])
file_extension = mimetypes.guess_extension(file_response.headers['Content-Type'])
file_hash = abs(hash(file_response.content))
download_path = f"/tmp/{file_hash}{file_extension}"
download_path = f'/tmp/{file_hash}{file_extension}'

with open(download_path, "wb") as file:
with open(download_path, 'wb') as file:
file.write(file_response.content)

return download_path
Loading