diff --git a/.github/scripts/build_assets/SeleniumRunner.py b/.github/scripts/build_assets/SeleniumRunner.py index 9fbb9207..b95d4a7c 100644 --- a/.github/scripts/build_assets/SeleniumRunner.py +++ b/.github/scripts/build_assets/SeleniumRunner.py @@ -89,20 +89,11 @@ class SeleniumRunner: :raises TimeoutException: happens when elements are not found. """ print("Uploading icomoon.json file...") - try: - self.click_hamburger_input() - - # find the file input and enter the file path - import_btn = self.driver.find_element(By.XPATH, "(//li[@class='file'])[1]//input") - import_btn.send_keys(icomoon_json_path) - except SeleniumTimeoutException as e: - print(e.stacktrace) - print("Selenium timed out. Couldn't find import button.") - self.close() - raise e - except Exception as e: - self.close() - raise e + self.click_hamburger_input() + + # find the file input and enter the file path + import_btn = self.driver.find_element(By.XPATH, "(//li[@class='file'])[1]//input") + import_btn.send_keys(icomoon_json_path) try: confirm_btn = WebDriverWait(self.driver, SeleniumRunner.MED_WAIT_IN_SEC).until( @@ -110,11 +101,8 @@ class SeleniumRunner: ) confirm_btn.click() except SeleniumTimeoutException as e: - print(e.stacktrace) - print("Cannot find the confirm button when uploading the icomoon.json", - "Ensure that the icomoon.json is in the correct format for Icomoon.io", - sep='\n') - self.close() + 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.") @@ -126,39 +114,29 @@ class SeleniumRunner: the value is provided, it means the user want to take a screenshot of each icon. """ - try: - print("Uploading SVGs...") + print("Uploading SVGs...") - edit_mode_btn = self.driver.find_element_by_css_selector( - "div.btnBar button i.icon-edit" + edit_mode_btn = self.driver.find_element_by_css_selector( + "div.btnBar button i.icon-edit" + ) + edit_mode_btn.click() + + self.click_hamburger_input() + + for i in range(len(svgs)): + import_btn = self.driver.find_element_by_css_selector( + "li.file input[type=file]" ) - edit_mode_btn.click() + import_btn.send_keys(svgs[i]) + print(f"Uploaded {svgs[i]}") + self.test_for_possible_alert(self.SHORT_WAIT_IN_SEC, "Dismiss") + self.click_on_just_added_icon(screenshot_folder, i) - self.click_hamburger_input() + # take a screenshot of the icons that were just added + new_icons_path = str(Path(screenshot_folder, "new_icons.png").resolve()) + self.driver.save_screenshot(new_icons_path); - for i in range(len(svgs)): - import_btn = self.driver.find_element_by_css_selector( - "li.file input[type=file]" - ) - import_btn.send_keys(svgs[i]) - print(f"Uploaded {svgs[i]}") - self.test_for_possible_alert(self.SHORT_WAIT_IN_SEC, "Dismiss") - self.click_on_just_added_icon(screenshot_folder, i) - - # take a screenshot of the icons that were just added - new_icons_path = str(Path(screenshot_folder, "new_icons.png").resolve()) - self.driver.save_screenshot(new_icons_path); - - # select all the svgs so that the newly added svg are part of the collection - 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() - print("Finished uploading the svgs...") - except Exception as e: - self.close() - raise e + print("Finished uploading the svgs...") def click_hamburger_input(self): """ @@ -167,20 +145,16 @@ class SeleniumRunner: input two times before the menu appears. :return: None. """ - try: - hamburger_input = self.driver.find_element_by_xpath( - "(//i[@class='icon-menu'])[2]" - ) + hamburger_input = self.driver.find_element_by_xpath( + "(//i[@class='icon-menu'])[2]" + ) - menu_appear_callback = ec.element_to_be_clickable( - (By.CSS_SELECTOR, "h1 ul.menuList2") - ) + menu_appear_callback = ec.element_to_be_clickable( + (By.CSS_SELECTOR, "h1 ul.menuList2") + ) - while not menu_appear_callback(self.driver): - hamburger_input.click() - except Exception as e: - self.close() - raise e + while not menu_appear_callback(self.driver): + hamburger_input.click() def test_for_possible_alert(self, wait_period: float, btn_text: str): """ @@ -204,25 +178,21 @@ class SeleniumRunner: Click on the most recently added icon so we can remove the colors and take a snapshot if needed. """ - try: - recently_uploaded_icon = WebDriverWait(self.driver, self.LONG_WAIT_IN_SEC).until( - ec.element_to_be_clickable((By.XPATH, "//div[@id='set0']//mi-box[1]//div")) - ) - recently_uploaded_icon.click() + recently_uploaded_icon = WebDriverWait(self.driver, self.LONG_WAIT_IN_SEC).until( + ec.element_to_be_clickable((By.XPATH, "//div[@id='set0']//mi-box[1]//div")) + ) + recently_uploaded_icon.click() - self.remove_color_from_icon() + self.remove_color_from_icon() - if screenshot_folder: - screenshot_path = str(Path(screenshot_folder, f"screenshot_{index}.png").resolve()) - self.driver.save_screenshot(screenshot_path) - print("Took screenshot and saved it at " + screenshot_path) + if screenshot_folder: + screenshot_path = str(Path(screenshot_folder, f"screenshot_{index}.png").resolve()) + self.driver.save_screenshot(screenshot_path) + print("Took screenshot and saved it at " + screenshot_path) - close_btn = self.driver \ - .find_element_by_css_selector("div.overlayWindow i.icon-close") - close_btn.click() - except Exception as e: - self.close() - raise e + close_btn = self.driver \ + .find_element_by_css_selector("div.overlayWindow i.icon-close") + close_btn.click() def remove_color_from_icon(self): """ @@ -232,38 +202,45 @@ class SeleniumRunner: The color removal is also necessary so that the Icomoon-generated icons fit within one font symbol/ligiature. """ - color_tab = WebDriverWait(self.driver, self.SHORT_WAIT_IN_SEC).until( - ec.element_to_be_clickable((By.CSS_SELECTOR, "div.overlayWindow i.icon-droplet")) - ) - color_tab.click() + try: + color_tab = WebDriverWait(self.driver, self.SHORT_WAIT_IN_SEC).until( + ec.element_to_be_clickable((By.CSS_SELECTOR, "div.overlayWindow i.icon-droplet")) + ) + color_tab.click() - remove_color_btn = self.driver \ - .find_element_by_css_selector("div.overlayWindow i.icon-droplet-cross") - remove_color_btn.click() + remove_color_btn = self.driver \ + .find_element_by_css_selector("div.overlayWindow i.icon-droplet-cross") + remove_color_btn.click() + except SeleniumTimeoutException: + pass # do nothing cause sometimes, the color tab doesn't appear in the site def download_icomoon_fonts(self, zip_path: Path): """ Download the icomoon.zip from icomoon.io. :param zip_path: the path to the zip file after it's downloaded. """ - try: - print("Downloading Font files...") - self.driver.find_element_by_css_selector( - "a[href='#/select/font']" - ).click() + # select all the svgs so that the newly added svg are part of the collection + 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() - self.test_for_possible_alert(self.MED_WAIT_IN_SEC, "Continue") - download_btn = WebDriverWait(self.driver, SeleniumRunner.LONG_WAIT_IN_SEC).until( - ec.presence_of_element_located((By.CSS_SELECTOR, "button.btn4 span")) - ) - download_btn.click() - if self.wait_for_zip(zip_path): - print("Font files downloaded.") - else: - raise TimeoutError(f"Couldn't find {zip_path} after download button was clicked.") - except Exception as e: - self.close() - raise e + print("Downloading Font files...") + font_tab = self.driver.find_element_by_css_selector( + "a[href='#/select/font']" + ) + font_tab.click() + + self.test_for_possible_alert(self.MED_WAIT_IN_SEC, "Continue") + download_btn = WebDriverWait(self.driver, SeleniumRunner.LONG_WAIT_IN_SEC).until( + ec.presence_of_element_located((By.CSS_SELECTOR, "button.btn4 span")) + ) + download_btn.click() + if self.wait_for_zip(zip_path): + print("Font files downloaded.") + else: + raise TimeoutError(f"Couldn't find {zip_path} after download button was clicked.") def wait_for_zip(self, zip_path: Path) -> bool: """ diff --git a/.github/scripts/icomoon_build.py b/.github/scripts/icomoon_build.py index da8f0236..303a7ffc 100644 --- a/.github/scripts/icomoon_build.py +++ b/.github/scripts/icomoon_build.py @@ -1,4 +1,5 @@ from pathlib import Path +import sys from selenium.common.exceptions import TimeoutException # pycharm complains that build_assets is an unresolved ref @@ -11,8 +12,7 @@ def main(): args = arg_getters.get_selenium_runner_args() new_icons = filehandler.find_new_icons(args.devicon_json_path, args.icomoon_json_path) if len(new_icons) == 0: - print("No files need to be uploaded. Ending script...") - return + sys.exit("No files need to be uploaded. Ending script...") # print list of new icons print("List of new icons:", *new_icons, sep = "\n") @@ -32,10 +32,11 @@ def main(): filehandler.rename_extracted_files(args.download_path) print("Task completed.") except TimeoutException as e: - print(e) - print(e.stacktrace) + sys.exit("Selenium Time Out Error: \n" + str(e)) + except Exception as e: + sys.exit(e) finally: - runner.close() + runner.close() if __name__ == "__main__": diff --git a/.github/scripts/icomoon_peek.py b/.github/scripts/icomoon_peek.py index c5be4acf..cccfce5d 100644 --- a/.github/scripts/icomoon_peek.py +++ b/.github/scripts/icomoon_peek.py @@ -38,11 +38,11 @@ def main(): runner.upload_svgs(svgs, screenshot_folder) print("Task completed.") except TimeoutException as e: - print("Selenium Time Out Error: ", e.stacktrace, sep='\n') + sys.exit("Selenium Time Out Error: \n" + str(e)) except Exception as e: - print(e) + sys.exit(e) finally: - runner.close() + runner.close() def find_object_added_in_this_pr(icons: List[dict], pr_title: str): diff --git a/.github/workflows/build_icons.yml b/.github/workflows/build_icons.yml index cf1ef97e..1cef6ed1 100644 --- a/.github/workflows/build_icons.yml +++ b/.github/workflows/build_icons.yml @@ -34,7 +34,7 @@ jobs: run: npm run build-css - name: Upload screenshot of the newly made icons id: imgur_step - uses: devicons/public-upload-to-imgur@v2 + uses: devicons/public-upload-to-imgur@v2.1 if: success() with: path: ./new_icons.png diff --git a/.github/workflows/peek_icons.yml b/.github/workflows/peek_icons.yml index 140221fe..90ed6fba 100644 --- a/.github/workflows/peek_icons.yml +++ b/.github/workflows/peek_icons.yml @@ -9,9 +9,6 @@ jobs: runs-on: windows-2019 steps: - uses: actions/checkout@v2 - with: - ref: ${{ github.head_ref }} - repository: ${{ github.event.pull_request.head.repo.full_name}} - name: Setup Python v3.8 uses: actions/setup-python@v2 with: @@ -36,14 +33,14 @@ jobs: path: ./geckodriver.log - name: Upload screenshot of the newly made icons id: icons_overview_img_step - uses: devicons/public-upload-to-imgur@v2 + uses: devicons/public-upload-to-imgur@v2.1 if: success() with: path: ./screenshots/new_icons.png client_id: ${{secrets.IMGUR_CLIENT_ID}} - name: Upload zoomed in screenshot of the newly made icons id: icons_detailed_img_step - uses: devicons/public-upload-to-imgur@v2 + uses: devicons/public-upload-to-imgur@v2.1 if: success() with: path: ./screenshots/screenshot_*.png diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3739a665..a1aca5df 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,6 +5,7 @@ First of all, thanks for taking the time to contribute! This project can only gr
Here are some terms that we will use in this repo:
+.svg
" refers to the svg
versions of the Icons.Here is an overview of what you have to do to submit your icons to the repo.
/icons
devicon.json
to include the new icon new icon: {{logoName}} ({{versions}})
/icons
devicon.json
to include the new Icon new icon: Icon name (versions)
Each icon can come in different versions. So far, we have:
+Each icon/svg can come in different versions. So far, we have:
-It is not mandatory to have 6 versions for each icon. An icon can only have one or two versions available. Just keep in mind that the minimum is 1 and the maximum 6 (for now). You must also have at least one version that can be make into an icon. -
--The plain and line versions (with or without wordmark) are designed to be available in the final icon font. -
--The original version are only available in svg format, so they do not need to be as simple and can contain numerous colors. -
-
-Some icons are really simple (like the Apple one), so the original version can be used as the plain version and as the icon font. In this case, you'll only need to make only one of the version (either "original" or "plain"). You can then add an alias in the devicon.json
so they can be found with either the "original" or "plain" naming convention. Note that this only applies to font icon versions only, not the SVG versions. SVG versions don't need aliases.
-
Notes
+
devicon.json
so they can be found with either the "original" or "plain" naming convention. Note: this only applies to font icon versions only, not the SVG versions.
+
+ Before you submit your logos/svgs, please ensure that they meet the following standard:
.svg
file contains one version of an icon in a 0 0 128 128
viewbox.(icon name)-(original|plain|line)(-wordmark?).
.svg
must use the fill
attribute instead of using classes
for colors. See here for more details.(Icon name)-(original|plain|line)(-wordmark?).
icons
folder.eps
file and as many .svg
files as versions available.eps
file contains all available versions of an icon. Each version is contained in a 128px by 128px artboard.eps
file.eps
file should contains all available versions of an icon. Each version is contained in a 128px by 128px artboard.svg
files for the Icondevicon.json
- Before you open a PR into Devicon, you'd have to update the devicon.json
. This is essential for our build script to work and to document your work.
+ Before you open a PR into Devicon, you must update the devicon.json
. This is essential for our build script to work and to document your work.
- Here is the object that each of your logo must have: + Here is the object that each of your Icon must have:
@@ -103,7 +119,7 @@ Some icons are really simple (like the Apple one), so the original version can b Here is what VersionString means:-
- It's the version part of an `svg` file's name
+- It's the version part of an
svg
file's name- If you have "html5-original", the version string would be "original"
- If you have "react-line-wordmark", the version string would be "line-wordmark"
- See naming conventions section for more details
@@ -127,19 +143,19 @@ Some icons are really simple (like the Apple one), so the original version can b As an example, let's assume you have created the svgs for Redhat and Amazon Web Services logos.For the Redhat svg, you have the "original", "original-wordmark", "plain", and "plain-wordmark" versions.
-For the Amazon Web Services svgs, you have the following versions: "original", "original-wordmark", "plain-wordmark". The "original" version is simple enough to be a "plain" version as well. Note that we are not using the acronym AWS.
+For the Amazon Web Services svgs, you have the "original", "original-wordmark", "plain-wordmark" versions. The "original" version is simple enough to be a "plain" version as well. Note that we are not using the acronym AWS.
- Put the svgs for each logo that you have into its own folders in
/icons
- This means you would create two folders: one for
-amazonwebservices
and one forredhat
- Note: don't do this in the same commits. We want to have each logo in its own PR so don't create these two folders in the same commit
+- Note: don't do this in the same commits; we want to have each Icon in its own PR.
- - Update the
-devicon.json
to include the icon (or variations) + Update thedevicon.json
-
- For the
redhat
, you would do this +- For
-redhat
, you would do this{ @@ -193,17 +209,16 @@ As an example, let's assume you have created the svgs for Redhat and Amazon Web { "base": "original", // here is the base version that we will upload to Icomoon "alias": "plain" // this is its alias. Our script will create a reference so users can search using "original" or "plain" for this icon - // note that you don't provide aliases for the svg version. If "original" is not a font version (i.e can't be made into a font), there's no need to provide it with a plain alias + // note that you don't provide aliases for the svg version. If "original" can't be made into a font, there's no need to provide it with a plain alias } ] }
- Note: again, don't do this in the same commits. We want to have each logo in its own PR so don't create two folders in the same commit
- Create a separate pull request (PR) for each icon (no matter how many variations). +
- Create a separate pull request (PR) for each Icon.
- This means you would have to create two PRs
- For Amazon Web Services, the branch name would be icons/amazonwebservices.
@@ -211,7 +226,7 @@ As an example, let's assume you have created the svgs for Redhat and Amazon Web- - Include the name of the icon in the pull request. Follow this format: "new icon: {{logoName}} ({{versions}})" + Include the name of the icon in the pull request. Follow this format: "new icon: Icon name (versions}})"
- For Amazon Web Services, your PR title should be "new icon: amazonwebservices (original, original-wordmark, plain-wordmark)"
- For Redhat, your PR title should be "new icon: redhat (original, original-wordmark, plain, plain-wordmark)"
@@ -222,12 +237,12 @@ As an example, let's assume you have created the svgs for Redhat and Amazon Web
Requesting an Icon
-When you want to request a new icon please feel free to create a issue following some simple guidelines:
+To request an icon, you can create an issue in the repo. Please follow these simple guidelines:
- Search for other issues already requesting the icon
- If an issue doesn't exist, create an issue naming it "Icon request: name-of-the-icon".
-- Please create separated issues for each icon
-- optional: Include links where the icon can be found
+- Please create a separate issues for each icon
+- Optional: include links where the icon can be found
@@ -241,5 +256,6 @@ As an example, let's assume you have created the svgs for Redhat and Amazon WebThere are also other tasks that we are automating, such as:
\ No newline at end of file
- Ensure code quality is up to standard
-- Upload svgs to icomoon.io and take a screenshot for check. +
- Upload svgs to icomoon.io and take a screenshot to check that it looks good. +
- Comment on the PR so maintainers don't have to manually upload icon result.