mirror of
https://github.com/konpa/devicon.git
synced 2025-08-11 17:14:27 +02:00
Add fix for bad zip file and logging for build (#1069)
This commit is contained in:
@@ -27,7 +27,7 @@ class BuildSeleniumRunner(SeleniumRunner):
|
||||
:param icomoon_json_path: a path to the iconmoon.json.
|
||||
:raises TimeoutException: happens when elements are not found.
|
||||
"""
|
||||
print("Uploading icomoon.json file...")
|
||||
print("Uploading icomoon.json file...", file=self.log_output)
|
||||
|
||||
# find the file input and enter the file path
|
||||
import_btn = self.driver.find_element_by_css_selector(
|
||||
@@ -44,7 +44,7 @@ class BuildSeleniumRunner(SeleniumRunner):
|
||||
raise Exception("Cannot find the confirm button when uploading the icomoon.json" \
|
||||
"Ensure that the icomoon.json is in the correct format for Icomoon.io")
|
||||
|
||||
print("JSON file uploaded.")
|
||||
print("JSON file uploaded.", file=self.log_output)
|
||||
|
||||
def upload_svgs(self, svgs: List[str], screenshot_folder: str):
|
||||
"""
|
||||
@@ -52,7 +52,7 @@ class BuildSeleniumRunner(SeleniumRunner):
|
||||
:param svgs: a list of svg Paths that we'll upload to icomoon.
|
||||
:param screenshot_folder: the name of the screenshot_folder.
|
||||
"""
|
||||
print("Uploading SVGs...")
|
||||
print("Uploading SVGs...", file=self.log_output)
|
||||
|
||||
import_btn = self.driver.find_element_by_css_selector(
|
||||
SeleniumRunner.SET_IMPORT_BUTTON_CSS
|
||||
@@ -63,7 +63,7 @@ class BuildSeleniumRunner(SeleniumRunner):
|
||||
err_messages = []
|
||||
for i in range(len(svgs)):
|
||||
import_btn.send_keys(svgs[i])
|
||||
print(f"Uploading {svgs[i]}")
|
||||
print(f"Uploading {svgs[i]}", file=self.log_output)
|
||||
|
||||
# see if there are stroke messages or replacing icon message
|
||||
# there should be none of the second kind
|
||||
@@ -83,8 +83,9 @@ class BuildSeleniumRunner(SeleniumRunner):
|
||||
raise Exception(f"Unexpected alert found: {alert}")
|
||||
|
||||
self.edit_svg()
|
||||
print(f"Finished editing icon.")
|
||||
print(f"Finished editing icon.", file=self.log_output)
|
||||
|
||||
print("Finished uploading all files.", file=self.log_output)
|
||||
if err_messages != []:
|
||||
message = "BuildSeleniumRunner - Issues found when uploading SVGs:\n"
|
||||
raise Exception(message + '\n'.join(err_messages))
|
||||
@@ -94,9 +95,9 @@ class BuildSeleniumRunner(SeleniumRunner):
|
||||
self.switch_toolbar_option(IcomoonOptionState.SELECT)
|
||||
self.select_all_icons_in_top_set()
|
||||
new_svgs_path = str(Path(screenshot_folder, "new_svgs.png").resolve())
|
||||
self.driver.save_screenshot(new_svgs_path);
|
||||
self.driver.save_screenshot(new_svgs_path)
|
||||
|
||||
print("Finished uploading the svgs...")
|
||||
print("Finished uploading the svgs...", file=self.log_output)
|
||||
|
||||
def take_icon_screenshot(self, screenshot_folder: str):
|
||||
"""
|
||||
@@ -105,7 +106,7 @@ class BuildSeleniumRunner(SeleniumRunner):
|
||||
:param screenshot_folder: the name of the screenshot_folder.
|
||||
"""
|
||||
# take pictures
|
||||
print("Taking screenshot of the new icons...")
|
||||
print("Taking screenshot of the new icons...", file=self.log_output)
|
||||
self.go_to_generate_font_page()
|
||||
|
||||
# take an overall screenshot of the icons that were just added
|
||||
@@ -113,8 +114,11 @@ class BuildSeleniumRunner(SeleniumRunner):
|
||||
new_icons_path = str(Path(screenshot_folder, "new_icons.png").resolve())
|
||||
main_content_xpath = "/html/body/div[4]/div[2]/div/div[1]"
|
||||
main_content = self.driver.find_element_by_xpath(main_content_xpath)
|
||||
|
||||
# wait a bit for all the icons to load before we take a pic
|
||||
time.sleep(SeleniumRunner.MED_WAIT_IN_SEC)
|
||||
main_content.screenshot(new_icons_path)
|
||||
print("Saved screenshot of the new icons...")
|
||||
print("Saved screenshot of the new icons...", file=self.log_output)
|
||||
|
||||
def go_to_generate_font_page(self):
|
||||
"""
|
||||
@@ -137,7 +141,7 @@ class BuildSeleniumRunner(SeleniumRunner):
|
||||
what the icons look like.
|
||||
:param zip_path: the path to the zip file after it's downloaded.
|
||||
"""
|
||||
print("Downloading Font files...")
|
||||
print("Downloading Font files...", file=self.log_output)
|
||||
if self.current_page != IcomoonPage.SELECTION:
|
||||
self.go_to_page(IcomoonPage.SELECTION)
|
||||
|
||||
@@ -149,7 +153,7 @@ class BuildSeleniumRunner(SeleniumRunner):
|
||||
)
|
||||
download_btn.click()
|
||||
if self.wait_for_zip(zip_path):
|
||||
print("Font files downloaded.")
|
||||
print("Font files downloaded.", file=self.log_output)
|
||||
else:
|
||||
raise TimeoutError(f"Couldn't find {zip_path} after download button was clicked.")
|
||||
|
||||
|
@@ -28,7 +28,7 @@ class PeekSeleniumRunner(SeleniumRunner):
|
||||
:return an array of svgs with strokes as strings. These show which icon
|
||||
contains stroke.
|
||||
"""
|
||||
print("Peeking SVGs...")
|
||||
print("Peeking SVGs...", file=self.log_output)
|
||||
|
||||
import_btn = self.driver.find_element_by_css_selector(
|
||||
SeleniumRunner.GENERAL_IMPORT_BUTTON_CSS
|
||||
@@ -37,13 +37,13 @@ class PeekSeleniumRunner(SeleniumRunner):
|
||||
svgs_with_strokes = []
|
||||
for i in range(len(svgs)):
|
||||
import_btn.send_keys(svgs[i])
|
||||
print(f"Uploaded {svgs[i]}")
|
||||
print(f"Uploaded {svgs[i]}", file=self.log_output)
|
||||
|
||||
alert = self.test_for_possible_alert(self.SHORT_WAIT_IN_SEC)
|
||||
if alert == None:
|
||||
pass # all good
|
||||
elif alert == IcomoonAlerts.STROKES_GET_IGNORED_WARNING:
|
||||
print(f"- This icon contains strokes: {svgs[i]}")
|
||||
print(f"- This icon contains strokes: {svgs[i]}", file=self.log_output)
|
||||
svg = Path(svgs[i])
|
||||
svgs_with_strokes.append(f"- {svg.name}")
|
||||
self.click_alert_button(self.ALERTS[alert]["buttons"]["DISMISS"])
|
||||
@@ -57,9 +57,9 @@ class PeekSeleniumRunner(SeleniumRunner):
|
||||
new_svgs_path = str(Path(screenshot_folder, "new_svgs.png").resolve())
|
||||
icon_set_xpath = "/html/body/div[4]/div[1]/div[2]/div[1]"
|
||||
icon_set = self.driver.find_element_by_xpath(icon_set_xpath)
|
||||
icon_set.screenshot(new_svgs_path);
|
||||
icon_set.screenshot(new_svgs_path)
|
||||
|
||||
print("Finished peeking the svgs...")
|
||||
print("Finished peeking the svgs...", file=self.log_output)
|
||||
return svgs_with_strokes
|
||||
|
||||
def peek_icons(self, screenshot_folder: str, icon_info: dict):
|
||||
@@ -68,7 +68,7 @@ class PeekSeleniumRunner(SeleniumRunner):
|
||||
:param screenshot_folder: the name of the screenshot_folder.
|
||||
:param icon_info: a dictionary containing info on an icon. Taken from the devicon.json.
|
||||
"""
|
||||
print("Begin peeking at the icons...")
|
||||
print("Begin peeking at the icons...", file=self.log_output)
|
||||
# ensure all icons in the set is selected.
|
||||
self.select_all_icons_in_top_set()
|
||||
self.go_to_page(IcomoonPage.GENERATE_FONT)
|
||||
@@ -119,4 +119,4 @@ class PeekSeleniumRunner(SeleniumRunner):
|
||||
|
||||
i += 1
|
||||
|
||||
print("Finished peeking the icons...")
|
||||
print("Finished peeking the icons...", file=self.log_output)
|
||||
|
@@ -1,5 +1,6 @@
|
||||
from pathlib import Path
|
||||
from selenium.webdriver.common import service
|
||||
from io import FileIO
|
||||
import sys
|
||||
|
||||
from selenium.webdriver.firefox.webdriver import WebDriver
|
||||
from selenium.webdriver.firefox.service import Service
|
||||
@@ -8,6 +9,7 @@ from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as ec
|
||||
from selenium.common.exceptions import TimeoutException as SeleniumTimeoutException
|
||||
from selenium.common.exceptions import ElementNotInteractableException
|
||||
|
||||
from build_assets.selenium_runner.enums import IcomoonOptionState, IcomoonPage, IcomoonAlerts
|
||||
|
||||
@@ -106,7 +108,7 @@ class SeleniumRunner:
|
||||
}
|
||||
|
||||
def __init__(self, download_path: str,
|
||||
geckodriver_path: str, headless: bool):
|
||||
geckodriver_path: str, headless: bool, log_output: FileIO=sys.stdout):
|
||||
"""
|
||||
Create a SeleniumRunner object.
|
||||
:param download_path: the location where you want to download
|
||||
@@ -117,7 +119,16 @@ class SeleniumRunner:
|
||||
self.driver = None
|
||||
# default values when we open Icomoon
|
||||
self.current_option_state = IcomoonOptionState.SELECT
|
||||
"""
|
||||
Track the current option in the tool bar.
|
||||
"""
|
||||
|
||||
self.current_page = IcomoonPage.SELECTION
|
||||
"""Track the current page the driver is on."""
|
||||
|
||||
file=self.log_output = log_output
|
||||
"""The log output stream. Default is stdout."""
|
||||
|
||||
self.set_browser_options(download_path, geckodriver_path, headless)
|
||||
|
||||
def set_browser_options(self, download_path: str, geckodriver_path: str,
|
||||
@@ -145,7 +156,7 @@ class SeleniumRunner:
|
||||
options.set_preference("browser.download.dir", download_path)
|
||||
options.headless = headless
|
||||
|
||||
print("Activating browser client...")
|
||||
print("Activating browser client...", file=self.log_output)
|
||||
self.driver = self.create_driver_instance(options, geckodriver_path)
|
||||
|
||||
self.driver.get(self.ICOMOON_URL)
|
||||
@@ -153,7 +164,7 @@ class SeleniumRunner:
|
||||
WebDriverWait(self.driver, self.LONG_WAIT_IN_SEC).until(
|
||||
ec.element_to_be_clickable((By.XPATH, "(//i[@class='icon-menu'])[2]"))
|
||||
)
|
||||
print("Accessed icomoon.io")
|
||||
print("Accessed icomoon.io", file=self.log_output)
|
||||
|
||||
def create_driver_instance(self, options: Options, geckodriver_path: str):
|
||||
"""
|
||||
@@ -163,44 +174,37 @@ class SeleniumRunner:
|
||||
:param geckodriver_path: the path to the firefox executable.
|
||||
the icomoon.zip to.
|
||||
"""
|
||||
retries = SeleniumRunner.MAX_RETRY
|
||||
finished = False
|
||||
driver = None
|
||||
err_msgs = [] # keep for logging purposes
|
||||
while not finished and retries > 0:
|
||||
for i in range(SeleniumRunner.MAX_RETRY):
|
||||
try:
|
||||
# order matters, don't change the lines below
|
||||
finished = True # signal we are done in case we are actually done
|
||||
|
||||
# customize the local server
|
||||
service = None
|
||||
# first retry: use 8080
|
||||
# first try: use 8080
|
||||
# else: random
|
||||
if retries == SeleniumRunner.MAX_RETRY:
|
||||
if i == 0:
|
||||
service = Service(executable_path=geckodriver_path, port=8080)
|
||||
else:
|
||||
service = Service(executable_path=geckodriver_path)
|
||||
driver = WebDriver(options=options, service=service)
|
||||
except SeleniumTimeoutException as e:
|
||||
# retry. This is intended to catch "no connection could be made" error
|
||||
retries -= 1
|
||||
finished = False # flip the var so we can retry
|
||||
msg = f"Retry {retries}/{SeleniumRunner.MAX_RETRY} SeleniumTimeoutException: {e.msg}"
|
||||
print(msg)
|
||||
err_msgs.append(msg)
|
||||
except Exception as e:
|
||||
# anything else: unsure if retry works. Just end the retry
|
||||
msg = f"Retry {retries}/{SeleniumRunner.MAX_RETRY} Exception: {e}"
|
||||
# retry. This is intended to catch "no connection could be made" error
|
||||
# anything else: unsure if retry works. Still retry
|
||||
msg = f"Retry {i + 1}/{SeleniumRunner.MAX_RETRY} Exception: {e}"
|
||||
err_msgs.append(msg)
|
||||
print(msg)
|
||||
print(msg, file=self.log_output)
|
||||
else:
|
||||
# works fine
|
||||
break
|
||||
else:
|
||||
# out of retries
|
||||
# handle situation when we can't make a driver
|
||||
err_msg_formatted = '\n'.join(reversed(err_msgs))
|
||||
msg = f"Unable to create WebDriver Instance:\n{err_msg_formatted}"
|
||||
raise Exception(msg)
|
||||
|
||||
if driver is not None:
|
||||
return driver
|
||||
return driver
|
||||
|
||||
err_msg_formatted = '\n'.join(reversed(err_msgs))
|
||||
msg = f"Unable to create WebDriver Instance:\n{err_msg_formatted}"
|
||||
raise Exception(msg)
|
||||
|
||||
def switch_toolbar_option(self, option: IcomoonOptionState):
|
||||
"""
|
||||
@@ -311,7 +315,7 @@ class SeleniumRunner:
|
||||
edit_screen = self.driver.find_element_by_css_selector(
|
||||
edit_screen_selector)
|
||||
edit_screen.screenshot(screenshot_path)
|
||||
print("Took screenshot of svg and saved it at " + screenshot_path)
|
||||
print("Took screenshot of svg and saved it at " + screenshot_path, file=self.log_output)
|
||||
|
||||
close_btn = self.driver \
|
||||
.find_element_by_css_selector("div.overlayWindow i.icon-close")
|
||||
@@ -334,11 +338,22 @@ class SeleniumRunner:
|
||||
"""
|
||||
Select all the svgs in the top most (latest) set.
|
||||
"""
|
||||
self.click_hamburger_input()
|
||||
select_all_button = WebDriverWait(self.driver, self.LONG_WAIT_IN_SEC).until(
|
||||
ec.element_to_be_clickable((By.XPATH, "//button[text()='Select All']"))
|
||||
)
|
||||
select_all_button.click()
|
||||
tries = 3
|
||||
for i in range(tries):
|
||||
try:
|
||||
self.click_hamburger_input()
|
||||
select_all_button = WebDriverWait(self.driver, self.SHORT_WAIT_IN_SEC).until(
|
||||
ec.element_to_be_clickable((By.XPATH, "//button[text()='Select All']"))
|
||||
)
|
||||
select_all_button.click()
|
||||
except ElementNotInteractableException:
|
||||
# retry until it works
|
||||
pass
|
||||
else:
|
||||
break
|
||||
else:
|
||||
# after all tries and still can't click? Raise an error
|
||||
raise ElementNotInteractableException("Can't click the 'Select All' button in the hamburger input.")
|
||||
|
||||
def deselect_all_icons_in_top_set(self):
|
||||
"""
|
||||
@@ -366,5 +381,5 @@ class SeleniumRunner:
|
||||
"""
|
||||
Close the SeleniumRunner instance.
|
||||
"""
|
||||
print("Closing down SeleniumRunner...")
|
||||
print("Closing down SeleniumRunner...", file=self.log_output)
|
||||
self.driver.quit()
|
||||
|
Reference in New Issue
Block a user