diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index f2f7b08db..defc9fd99 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -10,12 +10,14 @@ jobs: strategy: matrix: python-version: [3.8, 3.11] # 3.12, pypy-3.9 - rf-version: [4.1.3, 5.0.1, 6.0.1] + rf-version: [5.0.1, 6.1.1, 7.0] + selenium-version: [4.14.0, 4.15.2, 4.16.0] #4.17.0, 4.18.0 + browser: [firefox, chrome, headlesschrome] #edge steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} with Robot Framework ${{ matrix.rf-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Setup Chrome @@ -26,6 +28,14 @@ jobs: - run: | echo Installed chromium version: ${{ steps.setup-chrome.outputs.chrome-version }} ${{ steps.setup-chrome.outputs.chrome-path }} --version + - name: Setup firefox + id: setup-firefox + uses: browser-actions/setup-firefox@v1 + with: + firefox-version: latest + - run: | + echo Installed firefox versions: ${{ steps.setup-firefox.outputs.firefox-version }} + ${{ steps.setup-firefox.outputs.firefox-path }} --version - name: Start xvfb run: | export DISPLAY=:99.0 @@ -42,6 +52,9 @@ jobs: pip install -r requirements.txt pip install robotstatuschecker>=1.4 pip install requests robotframework-pabot + - name: Install Seleninum v${{ matrix.selenium-version }} + run: | + pip install --upgrade selenium==${{ matrix.selenium-version }} - name: Install RF ${{ matrix.rf-version }} run: | pip install -U --pre robotframework==${{ matrix.rf-version }} @@ -56,29 +69,19 @@ jobs: run: | invoke gen-stub + # Temporarily ignoring pypy execution - name: Run tests with headless Chrome and with PyPy - if: matrix.python-version == 'pypy-3.9' + if: startsWith( matrix.python-version, 'pypy') == true run: | xvfb-run --auto-servernum python atest/run.py --nounit --zip headlesschrome - - name: Run tests with normal Chrome if CPython - if: matrix.python-version != 'pypy-3.9' - run: | - xvfb-run --auto-servernum python atest/run.py --zip chrome - - # Recognize for the moment this will NOT run as we aren't using Python 3.9 - - name: Run tests with headless Firefox with Python 3.9 and RF 4.1.3 - if: matrix.python-version == '3.9' && matrix.rf-version == '4.1.3' - run: | - xvfb-run --auto-servernum python atest/run.py --zip headlessfirefox - - - name: Run tests with normal Firefox with Python 3.9 and RF != 4.1.3 - if: matrix.python-version == '3.9' && matrix.rf-version != '4.1.3' + - name: Run tests with ${{ matrix.browser }} if CPython + if: startsWith( matrix.python-version, 'pypy') == false run: | - xvfb-run --auto-servernum python atest/run.py --zip firefox + xvfb-run --auto-servernum python atest/run.py --zip ${{ matrix.browser }} # - name: Run tests with Selenium Grid - # if: matrix.python-version == '3.11' && matrix.rf-version == '3.2.2' && matrix.python-version != 'pypy-3.7' + # if: matrix.python-version == '3.11' && matrix.rf-version == '3.2.2' && matrix.python-version != 'pypy-3.9' # run: | # wget --no-verbose --output-document=./selenium-server-standalone.jar http://selenium-release.storage.googleapis.com/3.141/selenium-server-standalone-3.141.59.jar # sudo chmod u+x ./selenium-server-standalone.jar @@ -87,5 +90,5 @@ jobs: - uses: actions/upload-artifact@v1 if: success() || failure() with: - name: Failed Test results + name: SeleniumLibrary Test results path: atest/zip_results diff --git a/BUILD.rst b/BUILD.rst index 9033fdaa4..ea33b0860 100644 --- a/BUILD.rst +++ b/BUILD.rst @@ -64,7 +64,8 @@ Testing ------- Make sure that adequate tests are executed before releases are created. -See ``_ for details. +For more information about unit tests see ``_ or for +acceptance tests see ``_. Preparation ----------- diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index de1a76316..ffb9d6ff8 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -3,21 +3,22 @@ Contribution guidelines These guidelines instruct how to submit issues and contribute code to the `SeleniumLibrary project`_. Other great ways to contribute include -answering questions and participating discussion on `robotframework-users`_ -mailing list and other forums as well as spreading the word about the -framework one way or the other. +answering questions and participating in discussions within the +#seleniumlibrary channel on the community `Robot Framework Slack`_, the +`Robot Framework Forum`_ and other channels as well as spreading the word +about the framework one way or the other. Submitting issues ================= Bugs and enhancements are tracked in the `issue tracker`_. If you are unsure if something is a bug or is a feature worth -implementing, you can first ask on `robotframework-users`_ list. This and +implementing, you can first ask within the `Robot Framework Slack`_. This and other similar forums, not the issue tracker, are also places where to ask general questions. -Before submitting a new issue, it is always a good idea to check is the -same bug or enhancement already reported. If it is, please add your +Before submitting a new issue, it is always a good idea to check if the +same bug or enhancement is already reported. If it is, please add your comments to the existing issue instead of creating a new one. Reporting bugs @@ -43,9 +44,11 @@ Enhancement requests Describe the new feature and use cases for it in as much detail as possible in an issue. Especially with larger enhancements, be prepared to -contribute the code in form of a pull request as explained below or to +contribute the code in the form of a pull request as explained below or to pay someone for the work. Consider also would it be better to implement this -functionality as a separate library outside the SeleniumLibrary. +functionality as a separate library outside the SeleniumLibrary. One option +here is to extend SeleniumLibrary using the public API or plug-in api. Please +see `extending documentation`_ for more details. Code contributions ================== @@ -88,17 +91,25 @@ We do, however, recommend to create dedicated branches for pull requests instead of creating them based on the master branch. This is especially important if you plan to work on multiple pull requests at the same time. -This project requires that pull request contains linear history of commits and -we do not allow that pull request contains merge commits or other noise. This helps -the review process and makes the maintenance easier for the project administrators. -Generally it is recommended to do `git pull --rebase` instead of the `git pull --merge` -when there is need pull changes from upstream. +This project asks that prior to making an enhancement pull request that you +discuss the enhancement with the team. We wish to avoid having you spend effort on an +ehancement that won't match with the project. We require that a pull request contains +linear history of commits and we do not allow that pull request contains merge commits +or other noise. This helps the review process and makes the maintenance easier for the +project administrators. Generally it is recommended to do `git pull --rebase` instead +of the `git pull --merge` when there is need pull changes from upstream. Coding conventions ------------------ +The SeleniumLibrary team is currently reviewing, revising, and updating +the coding conventions during Q1 2024. Knowing these coding conventions +are seen as a good practice, we are leaving these here as recommendations +in the mean time but are not forcing this as a requirement for accepting +pull requests. + SeleniumLibrary uses the general Python code conventions defined in -`PEP-8`_. In addition to that, we try to write `idiomatic Python`_ +`PEP-8`_. In addition to that, we try to write `idiomatic Python`_ or `"Pythonic" code`_ and follow the `SOLID principles`_. with all new code. An important guideline is that the code should be clear enough that comments are generally not needed. @@ -145,7 +156,7 @@ individual keywords. - All new enhancements or changes should have a note telling when the change was introduced. Often adding something like - ``New in SeleniumLibray 1.8.`` is enough. + ``New in SeleniumLibrary 1.8.`` is enough. Keyword documentation can be easily created using `invoke`_ task:: @@ -159,13 +170,13 @@ Tests When submitting a pull request with a new feature or a fix, you should always include tests for your changes. These tests prove that your changes work, help prevent bugs in the future, and help document what -your changes do. Depending an the change, you may need -``acceptance tests``\ *, ``unit tests``* or both. +your changes do. Depending an the change, you may need ``acceptance tests``, +``unit tests`` or both. Make sure to run all of the tests before submitting a pull request to be sure that your changes do not break anything. If you can, test in multiple browsers and versions (Firefox, Chrome, IE, Edge etc). Pull requests -are also automatically tested on `Travis CI`_. +are also automatically tested on `GitHub Actions`_. Acceptance tests ~~~~~~~~~~~~~~~~ @@ -173,20 +184,24 @@ Acceptance tests Most of SeleniumLibrary's testing is done using acceptance tests that naturally use Robot Framework itself for testing. Every new functionality or fix should generally get one or more acceptance tests. +For more details on acceptance tests and how to run the acceptance tests, +see `atest/README.rst`_. Unit tests ~~~~~~~~~~ Unit tests are great for testing internal logic and should be added when -appropriate. For more details see `Unit and acceptance -tests `__. +appropriate. For more details on unit tests and running them, see +`utest/README.rst`_. Continuous integration ---------------------- -SeleniumLibrary's continuous integration (CI) servers are visible through -`Travis CI`_. For more details about how to run test and how `Travis CI`_ -integration is implemented can be found from the `test/README.rst`_. +SeleniumLibrary uses GitHub Actions as it's continuous integration (CI) server. + +.. ToDo: re-add when explanation of GitHUb Actions is written + More details about how `GitHub Actions`_ integration is implemented can be + found within `<.github/CI/README.rst>. Finalizing pull requests ------------------------ @@ -198,7 +213,7 @@ Acknowledgments ~~~~~~~~~~~~~~~ If you have done any non-trivial change and would like to be credited, -remind us to add `acknowledge` tag to the issue. This way we will add +remind us to add ``acknowledge`` tag to the issue. This way we will add your name to the release notes, when next release is made. Resolving conflicts @@ -209,22 +224,26 @@ the same code as your changes. In that case you should `sync your fork`_ and `resolve conflicts`_ to allow for an easy merge. .. _SeleniumLibrary project: https://github.com/robotframework/SeleniumLibrary -.. _robotframework-users: http://groups.google.com/group/robotframework-users +.. _Robot Framework Slack: https://rf-invite.herokuapp.com/ +.. _Robot Framework Forum: https://forum.robotframework.org/c/libraries/lib-seleniumlibrary/11 .. _issue tracker: https://github.com/robotframework/SeleniumLibrary/issues .. _(SSCCE): http://sscce.org +.. _extending documentation: https://github.com/robotframework/SeleniumLibrary/blob/master/docs/extending/extending.rst .. _GitHub account: https://github.com/ .. _Git: https://git-scm.com .. _set up Git: https://help.github.com/articles/set-up-git/ .. _fork a repository: https://help.github.com/articles/fork-a-repo/ .. _use pull requests: https://help.github.com/articles/using-pull-requests .. _PEP-8: https://www.python.org/dev/peps/pep-0008/ -.. _idiomatic Python: http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html +.. _idiomatic Python: https://en.wikibooks.org/wiki/Python_Programming/Idioms +.. _"Pythonic" code: https://docs.python-guide.org/writing/style/ .. _SOLID principles: https://en.wikipedia.org/wiki/SOLID_(object-oriented_design) .. _PEP-257: https://www.python.org/dev/peps/pep-0257/ .. _invoke: http://www.pyinvoke.org/ -.. _Travis CI: https://travis-ci.org/robotframework/SeleniumLibrary -.. _test/README.rst`: https://github.com/robotframework/SeleniumLibrary/blob/master/test/README.rst +.. _GitHub Actions: https://github.com/robotframework/SeleniumLibrary/actions +.. _atest/README.rst: https://github.com/robotframework/SeleniumLibrary/tree/master/atest/README.rst +.. _utest/README.rst: https://github.com/robotframework/SeleniumLibrary/blob/master/utest/README.rst .. _sync your fork: https://help.github.com/articles/syncing-a-fork/ .. _resolve conflicts: https://help.github.com/articles/resolving-a-merge-conflict-from-the-command-line .. _Black: https://github.com/psf/black -.. _flake8: https://gitlab.com/pycqa/flake8 \ No newline at end of file +.. _flake8: https://github.com/PyCQA/flake8 \ No newline at end of file diff --git a/README.rst b/README.rst index 24a36213c..6948a9ea5 100644 --- a/README.rst +++ b/README.rst @@ -28,8 +28,8 @@ different versions and the overall project history. .. image:: https://img.shields.io/pypi/l/robotframework-seleniumlibrary.svg :target: https://www.apache.org/licenses/LICENSE-2.0 -.. image:: https://github.com/robotframework/SeleniumLibrary/workflows/SeleniumLibrary%20CI/badge.svg - :target: https://github.com/robotframework/SeleniumLibrary/actions?query=workflow%3A%22SeleniumLibrary+CI%22 +.. image:: https://github.com/robotframework/SeleniumLibrary/actions/workflows/CI.yml/badge.svg?branch=master + :target: https://github.com/robotframework/SeleniumLibrary/actions/workflows/CI.yml Keyword Documentation --------------------- diff --git a/atest/acceptance/2-event_firing_webdriver/event_firing_webdriver.robot b/atest/acceptance/2-event_firing_webdriver/event_firing_webdriver.robot index ea9d633c6..b31c8fa91 100644 --- a/atest/acceptance/2-event_firing_webdriver/event_firing_webdriver.robot +++ b/atest/acceptance/2-event_firing_webdriver/event_firing_webdriver.robot @@ -2,7 +2,7 @@ Library SeleniumLibrary event_firing_webdriver=${CURDIR}/../../resources/testlibs/MyListener.py Resource resource_event_firing_webdriver.robot Suite Setup Open Browser ${FRONT PAGE} ${BROWSER} alias=event_firing_webdriver -... remote_url=${REMOTE_URL} executable_path=%{WEBDRIVERPATH} +... remote_url=${REMOTE_URL} Suite Teardown Close All Browsers *** Variables *** @@ -12,10 +12,9 @@ ${event_firing_or_none} ${NONE} Open Browser To Start Page [Tags] NoGrid [Documentation] - ... LOG 1:20 DEBUG Wrapping driver to event_firing_webdriver. - ... LOG 1:22 INFO Got driver also from SeleniumLibrary. + ... LOG 1:31 DEBUG Wrapping driver to event_firing_webdriver. + ... LOG 1:33 INFO Got driver also from SeleniumLibrary. Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL} - ... executable_path=%{WEBDRIVERPATH} Event Firing Webdriver Go To (WebDriver) [Tags] NoGrid diff --git a/atest/acceptance/2-event_firing_webdriver/resource_event_firing_webdriver.robot b/atest/acceptance/2-event_firing_webdriver/resource_event_firing_webdriver.robot index ac68038d0..a224bc9bd 100644 --- a/atest/acceptance/2-event_firing_webdriver/resource_event_firing_webdriver.robot +++ b/atest/acceptance/2-event_firing_webdriver/resource_event_firing_webdriver.robot @@ -6,7 +6,7 @@ ${DESIRED_CAPABILITIES}= ${NONE} ${ROOT}= http://${SERVER}/html ${FRONT_PAGE}= ${ROOT}/ -*** Keyword *** +*** Keywords *** Go To Page "${relative url}" [Documentation] Goes to page diff --git a/atest/acceptance/__init__.robot b/atest/acceptance/__init__.robot index 632c26b08..cc9186ad0 100644 --- a/atest/acceptance/__init__.robot +++ b/atest/acceptance/__init__.robot @@ -1,4 +1,4 @@ -*** Setting *** +*** Settings *** Resource resource.robot Force Tags Regression diff --git a/atest/acceptance/big_list_of_naught_strings.robot b/atest/acceptance/big_list_of_naught_strings.robot index 3ab67c007..fbfaf6f22 100644 --- a/atest/acceptance/big_list_of_naught_strings.robot +++ b/atest/acceptance/big_list_of_naught_strings.robot @@ -1,4 +1,4 @@ -*** Setting *** +*** Settings *** Resource resource.robot Library BigListOfNaughtyStrings.BigListOfNaughtyStrings WITH NAME blns diff --git a/atest/acceptance/create_webdriver.robot b/atest/acceptance/create_webdriver.robot index ec62c1e99..0ee079522 100644 --- a/atest/acceptance/create_webdriver.robot +++ b/atest/acceptance/create_webdriver.robot @@ -1,4 +1,4 @@ -*** Setting *** +*** Settings *** Documentation Tests Webdriver Resource resource.robot Library Collections diff --git a/atest/acceptance/keywords/async_javascript.robot b/atest/acceptance/keywords/async_javascript.robot index 2a9f8fcbd..7fc72b198 100644 --- a/atest/acceptance/keywords/async_javascript.robot +++ b/atest/acceptance/keywords/async_javascript.robot @@ -19,6 +19,14 @@ Execute Async Javascript With ARGUMENTS and JAVASCRIPT Marker ... alert(arguments[0]); Alert Should Be Present 123 timeout=10 s +Execute Javascript with dictionary object + &{ARGS}= Create Dictionary key=value number=${1} boolean=${TRUE} + ${returned} Execute Async Javascript arguments[1](arguments[0]); ARGUMENTS ${ARGS} + Should Be True type($returned) == dict + Should Be Equal ${returned}[key] value + Should Be Equal ${returned}[number] ${1} + Should Be Equal ${returned}[boolean] ${TRUE} + Should Be Able To Return Javascript Primitives From Async Scripts Neither None Nor Undefined ${result} = Execute Async Javascript arguments[arguments.length - 1](123); Should Be Equal ${result} ${123} diff --git a/atest/acceptance/keywords/cookies.robot b/atest/acceptance/keywords/cookies.robot index 6ff52ccfb..81e22c453 100644 --- a/atest/acceptance/keywords/cookies.robot +++ b/atest/acceptance/keywords/cookies.robot @@ -1,4 +1,4 @@ -*** Setting *** +*** Settings *** Documentation Tests cookies Suite Setup Go To Page "cookies.html" Suite Teardown Delete All Cookies @@ -49,8 +49,9 @@ Add Cookie When Expiry Is Human Readable Data&Time Delete Cookie [Tags] Known Issue Safari Delete Cookie test - ${cookies} = Get Cookies - Should Be Equal ${cookies} far_future=timemachine; another=value + ${cookies} = Get Cookies as_dict=True + ${expected_cookies} Create Dictionary far_future=timemachine another=value + Dictionaries Should Be Equal ${cookies} ${expected_cookies} Non-existent Cookie Run Keyword And Expect Error @@ -107,17 +108,17 @@ Test Get Cookie Object Value Test Get Cookie Keyword Logging [Tags] NoGrid Known Issue Firefox [Documentation] - ... LOG 1:5 ${cookie} = name=far_future + ... LOG 1:5 GLOB: ${cookie} = name=far_future ... value=timemachine ... path=/ ... domain=localhost ... secure=False ... httpOnly=False - ... expiry=2024-09-15 11:22:33 + ... expiry=2024-09-15 *:22:33 ... extra={'sameSite': 'Lax'} ${cookie} = Get Cookie far_future -*** Keyword *** +*** Keywords *** Add Cookies Delete All Cookies Add Cookie test seleniumlibrary diff --git a/atest/acceptance/keywords/elements.robot b/atest/acceptance/keywords/elements.robot index 95bf90734..fa053b0ff 100644 --- a/atest/acceptance/keywords/elements.robot +++ b/atest/acceptance/keywords/elements.robot @@ -60,6 +60,92 @@ Get Element Attribute ${class}= Get Element Attribute ${second_div} class Should Be Equal ${class} Second Class +# About DOM Attributes and Properties +# ----------------------------------- +# When implementing the new `Get DOM Attirbute` and `Get Property` keywords (#1822), several +# questions were raised. Fundamentally what is the difference between a DOM attribute and +# a Property. As [1] explains "Attributes are defined by HTML. Properties are defined by the +# DOM (Document Object Model)." +# +# Below are some references which talk to some descriptions and oddities of DOM attributes +# and properties. +# +# References: +# [1] HTML attributes and DOM properties: +# https://angular.io/guide/binding-syntax#html-attribute-vs-dom-property +# [2] W3C HTML Specification - Section 13.1.2.3 Attributes: +# https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 +# [3] JavaScript.Info - Attributes and properties: +# https://javascript.info/dom-attributes-and-properties +# [4] "Which CSS properties are inherited?" - StackOverflow +# https://stackoverflow.com/questions/5612302/which-css-properties-are-inherited +# [5] MDN Web Docs: Attribute +# https://developer.mozilla.org/en-US/docs/Glossary/Attribute +# [6] MDN Web Docs: HTML attribute reference +# https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes + +Get DOM Attribute + # Test get DOM attribute + ${id}= Get DOM Attribute link:Link with id id + Should Be Equal ${id} some_id + # Test custom attribute + ${existing_custom_attr}= Get DOM Attribute id:emptyDiv data-id + Should Be Equal ${existing_custom_attr} my_id + ${doesnotexist_custom_attr}= Get DOM Attribute id:emptyDiv data-doesnotexist + Should Be Equal ${doesnotexist_custom_attr} ${None} + # Get non existing DOM Attribute + ${class}= Get DOM Attribute link:Link with id class + Should Be Equal ${class} ${NONE} + +More DOM Attributes + [Setup] Go To Page "forms/enabled_disabled_fields_form.html" + # Test get empty boolean attribute + ${disabled}= Get DOM Attribute css:input[name="disabled_input"] disabled + Should Be Equal ${disabled} true + # Test boolean attribute whose value is a string + ${disabled}= Get DOM Attribute css:input[name="disabled_password"] disabled + Should Be Equal ${disabled} true + # Test empty string as the value for the attribute + ${empty_value}= Get DOM Attribute css:input[name="disabled_password"] value + Should Be Equal ${empty_value} ${EMPTY} + # Test non-existing attribute + ${disabled}= Get DOM Attribute css:input[name="enabled_password"] disabled + Should Be Equal ${disabled} ${NONE} + +Get Property + [Setup] Go To Page "forms/enabled_disabled_fields_form.html" + ${tagName_prop}= Get Property css:input[name="readonly_empty"] tagName + Should Be Equal ${tagName_prop} INPUT + # Get a boolean property + ${isConnected}= Get Property css:input[name="readonly_empty"] isConnected + Should Be Equal ${isConnected} ${True} + # Test property which returns webelement + ${children_prop}= Get Property id:table1 children + Length Should Be ${children_prop} ${1} + ${isWebElement}= Evaluate isinstance($children_prop[0], selenium.webdriver.remote.webelement.WebElement) modules=selenium + Should Be Equal ${isWebElement} ${True} + # ToDo: need to test own versus inherited property + # ToDo: Test enumerated property + +Get "Attribute" That Is Both An DOM Attribute and Property + [Setup] Go To Page "forms/enabled_disabled_fields_form.html" + ${value_property}= Get Property css:input[name="readonly_empty"] value + ${value_attribute}= Get DOM Attribute css:input[name="readonly_empty"] value + Should Be Equal ${value_property} ${value_attribute} + +Modify "Attribute" That Is Both An DOM Attribute and Property + [Setup] Go To Page "forms/prefilled_email_form.html" + ${initial_value_property}= Get Property css:input[name="email"] value + ${initial_value_attribute}= Get DOM Attribute css:input[name="email"] value + Should Be Equal ${initial_value_property} ${initial_value_attribute} + Should Be Equal ${initial_value_attribute} Prefilled Email + Input Text css:input[name="email"] robot@robotframework.org + ${changed_value_property}= Get Property css:input[name="email"] value + ${changed_value_attribute}= Get DOM Attribute css:input[name="email"] value + Should Not Be Equal ${changed_value_property} ${changed_value_attribute} + Should Be Equal ${changed_value_attribute} Prefilled Email + Should Be Equal ${changed_value_property} robot@robotframework.org + Get Element Attribute Value Should Be Should Be Succesfull Element Attribute Value Should Be link=Absolute external link href http://www.google.com/ Element Attribute Value Should Be link=Absolute external link nothere ${None} diff --git a/atest/acceptance/keywords/frames.robot b/atest/acceptance/keywords/frames.robot index 0e0c10e61..c9d65d1e3 100644 --- a/atest/acceptance/keywords/frames.robot +++ b/atest/acceptance/keywords/frames.robot @@ -1,4 +1,4 @@ -*** Setting *** +*** Settings *** Documentation Tests frames Test Setup Go To Page "frames/frameset.html" Test Teardown UnSelect Frame diff --git a/atest/acceptance/keywords/javascript.robot b/atest/acceptance/keywords/javascript.robot index 2a2195cb2..a8d61fa7f 100644 --- a/atest/acceptance/keywords/javascript.robot +++ b/atest/acceptance/keywords/javascript.robot @@ -85,6 +85,14 @@ Execute Javascript from File With ARGUMENTS Marker ... 123 Alert Should Be Present 123 timeout=10 s +Execute Javascript with dictionary object + &{ARGS}= Create Dictionary key=value number=${1} boolean=${TRUE} + ${returned} Execute JavaScript return arguments[0] ARGUMENTS ${ARGS} + Should Be True type($returned) == dict + Should Be Equal ${returned}[key] value + Should Be Equal ${returned}[number] ${1} + Should Be Equal ${returned}[boolean] ${TRUE} + Open Context Menu [Tags] Known Issue Safari Go To Page "javascript/context_menu.html" diff --git a/atest/acceptance/keywords/textfields.robot b/atest/acceptance/keywords/textfields.robot index a537ecd64..1fa6f4522 100644 --- a/atest/acceptance/keywords/textfields.robot +++ b/atest/acceptance/keywords/textfields.robot @@ -1,4 +1,4 @@ -*** Setting *** +*** Settings *** Test Setup Go To Page "forms/prefilled_email_form.html" Resource ../resource.robot Force Tags Known Issue Internet Explorer @@ -39,7 +39,7 @@ Input Password Should Not Log Password String ... LOG 1:8 DEBUG STARTS: Remote response ... LOG 1:9 DEBUG Finished Request ... LOG 1:10 INFO Temporally setting log level to: NONE - ... LOG 1:11 INFO Log level changed from NONE to DEBUG. + ... LOG 1:11 ANY Log level changed from NONE to DEBUG. ... LOG 1:12 NONE ... LOG 2:1 INFO Typing text 'username' into text field 'username_field'. Input Password password_field password diff --git a/atest/acceptance/keywords/textfields_html5.robot b/atest/acceptance/keywords/textfields_html5.robot index 72ebe41ac..be8901134 100644 --- a/atest/acceptance/keywords/textfields_html5.robot +++ b/atest/acceptance/keywords/textfields_html5.robot @@ -1,4 +1,4 @@ -*** Setting *** +*** Settings *** Test Setup Go To Page "forms/html5_input_types.html" Resource ../resource.robot diff --git a/atest/acceptance/locators/locator_parsing.robot b/atest/acceptance/locators/locator_parsing.robot index eca57d054..3ae3a59aa 100644 --- a/atest/acceptance/locators/locator_parsing.robot +++ b/atest/acceptance/locators/locator_parsing.robot @@ -47,11 +47,6 @@ Multiple Locators with double arrows as separator should work Multiple Locators strategy should be case-insensitive Page Should Contain Element cSs=div#div_id >> XpaTh=a[6] >> iD=image1_id -Multiple Locators as a List should work - ${element} = Get WebElement id:foo:bar - ${locator_list} = Create List id:div_id ${element} id:bar=foo - Page Should Contain Element ${locator_list} - When One Of Locator From Multiple Locators Is Not Found Keyword Fails Run Keyword And Expect Error ... Element with locator 'id:not_here' not found. diff --git a/atest/acceptance/multiple_browsers_multiple_windows.robot b/atest/acceptance/multiple_browsers_multiple_windows.robot index ceb0c2035..a8837965e 100644 --- a/atest/acceptance/multiple_browsers_multiple_windows.robot +++ b/atest/acceptance/multiple_browsers_multiple_windows.robot @@ -1,4 +1,4 @@ -*** Setting *** +*** Settings *** Documentation These tests must open own browser because windows opened by ... earlier tests would otherwise be visible to Get Window XXX keywords ... even if those windows were closed. diff --git a/atest/acceptance/multiple_browsers_options.robot b/atest/acceptance/multiple_browsers_options.robot index bcf5c1a33..14dfde440 100644 --- a/atest/acceptance/multiple_browsers_options.robot +++ b/atest/acceptance/multiple_browsers_options.robot @@ -9,51 +9,62 @@ Documentation Creating test which would work on all browser is not possible. *** Test Cases *** Chrome Browser With Selenium Options As String [Documentation] - ... LOG 1:3 DEBUG GLOB: *"goog:chromeOptions"* - ... LOG 1:3 DEBUG GLOB: *args": ["--disable-dev-shm-usage"?* + ... LOG 1:14 DEBUG GLOB: *"goog:chromeOptions"* + ... LOG 1:14 DEBUG GLOB: *args": ["--disable-dev-shm-usage"?* Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL} ... desired_capabilities=${DESIRED_CAPABILITIES} options=add_argument("--disable-dev-shm-usage") - ... executable_path=%{WEBDRIVERPATH} - + Chrome Browser With Selenium Options As String With Attribute As True [Documentation] - ... LOG 1:3 DEBUG GLOB: *"goog:chromeOptions"* - ... LOG 1:3 DEBUG GLOB: *args": ["--disable-dev-shm-usage"?* - ... LOG 1:3 DEBUG GLOB: *"--headless=new"* + ... LOG 1:14 DEBUG GLOB: *"goog:chromeOptions"* + ... LOG 1:14 DEBUG GLOB: *args": ["--disable-dev-shm-usage"?* + ... LOG 1:14 DEBUG GLOB: *"--headless=new"* Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL} ... desired_capabilities=${DESIRED_CAPABILITIES} options=add_argument ( "--disable-dev-shm-usage" ) ; add_argument ( "--headless=new" ) - ... executable_path=%{WEBDRIVERPATH} - + Chrome Browser With Selenium Options With Complex Object [Tags] NoGrid [Documentation] - ... LOG 1:3 DEBUG GLOB: *"goog:chromeOptions"* - ... LOG 1:3 DEBUG GLOB: *"mobileEmulation": {"deviceName": "Galaxy S5"* - ... LOG 1:3 DEBUG GLOB: *args": ["--disable-dev-shm-usage"?* + ... LOG 1:14 DEBUG GLOB: *"goog:chromeOptions"* + ... LOG 1:14 DEBUG GLOB: *"mobileEmulation": {"deviceName": "Galaxy S5"* + ... LOG 1:14 DEBUG GLOB: *args": ["--disable-dev-shm-usage"?* Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL} ... desired_capabilities=${DESIRED_CAPABILITIES} options=add_argument ( "--disable-dev-shm-usage" ) ; add_experimental_option( "mobileEmulation" , { 'deviceName' : 'Galaxy S5'}) - ... executable_path=%{WEBDRIVERPATH} - + Chrome Browser With Selenium Options Object [Documentation] - ... LOG 2:3 DEBUG GLOB: *"goog:chromeOptions"* - ... LOG 2:3 DEBUG GLOB: *args": ["--disable-dev-shm-usage"?* + ... LOG 2:14 DEBUG GLOB: *"goog:chromeOptions"* + ... LOG 2:14 DEBUG GLOB: *args": ["--disable-dev-shm-usage"?* ${options} = Get Chrome Options Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL} ... desired_capabilities=${DESIRED_CAPABILITIES} options=${options} - ... executable_path=%{WEBDRIVERPATH} - + Chrome Browser With Selenium Options Invalid Method Run Keyword And Expect Error AttributeError: 'Options' object has no attribute 'not_here_method' ... Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL} ... desired_capabilities=${DESIRED_CAPABILITIES} options=not_here_method("arg1") - ... executable_path=%{WEBDRIVERPATH} Chrome Browser With Selenium Options Argument With Semicolon [Documentation] - ... LOG 1:3 DEBUG GLOB: *"goog:chromeOptions"* - ... LOG 1:3 DEBUG GLOB: *["has;semicolon"* + ... LOG 1:14 DEBUG GLOB: *"goog:chromeOptions"* + ... LOG 1:14 DEBUG GLOB: *["has;semicolon"* Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL} ... desired_capabilities=${DESIRED_CAPABILITIES} options=add_argument("has;semicolon") - ... executable_path=%{WEBDRIVERPATH} + +Chrome Browser with Selenium Options Ending With Semicolon + Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL} + ... desired_capabilities=${DESIRED_CAPABILITIES} options=add_argument("--disable-dev-shm-usage") ; + +Chrome Browser with Selenium Options Ending With A Few Semicolons + Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL} + ... desired_capabilities=${DESIRED_CAPABILITIES} options=add_argument("--disable-dev-shm-usage") ; ; ; + +Chrome Browser with Selenium Options Containing Empty Option + Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL} + ... desired_capabilities=${DESIRED_CAPABILITIES} options=add_argument ( "--disable-dev-shm-usage" ) ; ; add_argument ( "--headless=new" ) + +Chrome Browser with Selenium Options With A Missing Semicolon + Run Keyword And Expect Error ValueError: Unable to parse option: "add_argument ( "--disable-dev-shm-usage" ) add_argument ( "--headless=new" )" + ... Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL} + ... desired_capabilities=${DESIRED_CAPABILITIES} options=add_argument ( "--disable-dev-shm-usage" ) add_argument ( "--headless=new" ) diff --git a/atest/acceptance/open_and_close.robot b/atest/acceptance/open_and_close.robot index 9bb13c01d..aad19deb9 100644 --- a/atest/acceptance/open_and_close.robot +++ b/atest/acceptance/open_and_close.robot @@ -16,11 +16,11 @@ Close Browser Does Nothing When No Browser Is Opened Browser Open With Not Well-Formed URL Should Close [Documentation] Verify after incomplete 'Open Browser' browser closes - ... LOG 1.1:24 DEBUG STARTS: Opened browser with session id - ... LOG 1.1:24 DEBUG REGEXP: .*but failed to open url.* + ... LOG 1.1:35 DEBUG STARTS: Opened browser with session id + ... LOG 1.1:35 DEBUG REGEXP: .*but failed to open url.* ... LOG 2:2 DEBUG STARTS: DELETE ... LOG 2:5 DEBUG STARTS: Finished Request - Run Keyword And Expect Error * Open Browser bad.url.bad ${BROWSER} executable_path=%{WEBDRIVERPATH} + Run Keyword And Expect Error * Open Browser bad.url.bad ${BROWSER} Close All Browsers Switch to closed browser is possible diff --git a/atest/acceptance/resource.robot b/atest/acceptance/resource.robot index 2ff32f7c8..4bcaf38eb 100644 --- a/atest/acceptance/resource.robot +++ b/atest/acceptance/resource.robot @@ -1,10 +1,10 @@ -*** Setting *** +*** Settings *** Library SeleniumLibrary run_on_failure=Nothing implicit_wait=0.2 seconds Library Collections Library OperatingSystem Library DateTime -*** Variable *** +*** Variables *** ${SERVER}= localhost:7000 ${BROWSER}= firefox ${REMOTE_URL}= ${NONE} @@ -13,7 +13,7 @@ ${ROOT}= http://${SERVER}/html ${FRONT_PAGE}= ${ROOT}/ ${SPEED}= 0 -*** Keyword *** +*** Keywords *** Open Browser To Start Page [Documentation] This keyword also tests 'Set Selenium Speed' and 'Set Selenium Timeout' ... against all reason. diff --git a/atest/acceptance/windows.robot b/atest/acceptance/windows.robot index 733d59d16..25b6ab1f4 100644 --- a/atest/acceptance/windows.robot +++ b/atest/acceptance/windows.robot @@ -1,4 +1,4 @@ -*** Setting *** +*** Settings *** Documentation These tests must open own browser because windows opened by ... earlier tests would otherwise be visible to Get Window XXX keywords ... even if those windows were closed. @@ -114,6 +114,31 @@ Set Window Position using strings Should Be Equal ${x} ${200} Should Be Equal ${y} ${100} +Test Minimize and Maximize Will Actually Move and Resize Window + [Tags] Triage + Set Window Position 300 200 + Set Window Size 400 300 + ${isHidden}= Execute Javascript return document.hidden; + Should Not Be True ${isHidden} + + Minimize Browser Window + + ${isHidden}= Execute Javascript return document.hidden; + Should Be True ${isHidden} + + Maximize Browser Window + + ${isHidden}= Execute Javascript return document.hidden; + Should Not Be True ${isHidden} + + ${x} ${y}= Get Window Position + ${width} ${height}= Get Window Size + # Windows: Can't test for zero in multi-monitor setups + Should Not Be Equal ${x} ${300} + Should Not Be Equal ${y} ${200} + Should Be True ${width} > 400 + Should Be True ${height} > 300 + Select Window By Title After Close Window [Tags] Known Issue Internet Explorer Known Issue Safari Cannot Be Executed in IE diff --git a/docs/SeleniumLibrary-6.2.0.rst b/docs/SeleniumLibrary-6.2.0.rst new file mode 100644 index 000000000..542bb66a1 --- /dev/null +++ b/docs/SeleniumLibrary-6.2.0.rst @@ -0,0 +1,124 @@ +===================== +SeleniumLibrary 6.2.0 +===================== + + +.. default-role:: code + + +SeleniumLibrary_ is a web testing library for `Robot Framework`_ that utilizes +the Selenium_ tool internally. SeleniumLibrary 6.2.0 is a new release with +compatibility fixes for recent selenium versions and some bug fixes. + +If you have pip_ installed, just run + +:: + + pip install --upgrade robotframework-seleniumlibrary + +to install the latest available release or use + +:: + + pip install robotframework-seleniumlibrary==6.2.0 + +to install exactly this version. Alternatively you can download the source +distribution from PyPI_ and install it manually. + +SeleniumLibrary 6.2.0 was released on Friday November 24, 2023. SeleniumLibrary supports +Python 3.8 through 3.11, Selenium 4.12.0 through 4.15.2 and +Robot Framework 5.0.1 and 6.1.1. + +.. _Robot Framework: http://robotframework.org +.. _SeleniumLibrary: https://github.com/robotframework/SeleniumLibrary +.. _Selenium: http://seleniumhq.org +.. _pip: http://pip-installer.org +.. _PyPI: https://pypi.python.org/pypi/robotframework-seleniumlibrary +.. _issue tracker: https://github.com/robotframework/SeleniumLibrary/issues?q=milestone%3Av6.2.0 + + +.. contents:: + :depth: 2 + :local: + +Most important enhancements +=========================== + +- Remove deprecated headless option for chrome and firefox. (`#1858`_) + If one specified either `headlesschrome` or `headlessfirefox` as the browser within the + Open Browser keyword, then the library would handle setting this option with the underlying + Selenium driver. But the methods to do so were depracted and then removed in Selenium + v4.13.0. Thus one was not getting a headless browser in these instances. This resolves that + issue. + +- Resolve issue with service log_path now log_output. (`#1870`_) + Selenium changed the arguments for the service log within v4.13.0. This change allows for a + seamless usage across versions before and after v4.13.0. + +- Execute JavaScript converts arguments to strings with robot==6.1 (`#1843`_) + If any ARGUMENTS were passed into either the `Execute Javascript` or `Execute Async Javascript` + then they were converted to strings even if they were of some other type. This has been + corrected within this release. + +Acknowledgements +================ + +I want to thank the following for helping to get out this release, + +- `René Rohner `_ for pointing out that Create Webdriver had a + mutable default value (`#1817`_) +- `Kieran Trautwein `_ for resolving the issue with + deprecated headless option for chrome and firefox. (`#1858`_) +- `Nicholas Bollweg `_ for assisting in resolving the issue + with service log_path now log_output. (`#1870`_) +- `Igor Kozyrenko `_ for reporting the argument issue with Execute + JavaScript and `René Rohner `_for resolving it. (`#1843`_) +- `Robin Matz `_ for improving the documentation on page load + timeout (`#1821`_) +- `Dor Blayzer `_ for reporting and fixing the SeleniumLibrary CI badge. () + +and **Yuri Verweij, Lisa Crispin, and Tatu Aalto**. + +Full list of fixes and enhancements +=================================== + +.. list-table:: + :header-rows: 1 + + * - ID + - Type + - Priority + - Summary + * - `#1817`_ + - bug + - critical + - Create Webdriver has mutable default value + * - `#1858`_ + - bug + - critical + - Remove deprecated headless option for chrome and firefox. + * - `#1870`_ + - bug + - critical + - Resolve issue with service log_path now log_output. + * - `#1843`_ + - bug + - high + - Execute JavaScript converts arguments to strings with robot==6.1 + * - `#1821`_ + - enhancement + - medium + - Improve documentation on page load timeout + * - `#1872`_ + - --- + - medium + - fix: Selenium CI badge show wrong status + +Altogether 6 issues. View on the `issue tracker `__. + +.. _#1817: https://github.com/robotframework/SeleniumLibrary/issues/1817 +.. _#1858: https://github.com/robotframework/SeleniumLibrary/issues/1858 +.. _#1870: https://github.com/robotframework/SeleniumLibrary/issues/1870 +.. _#1843: https://github.com/robotframework/SeleniumLibrary/issues/1843 +.. _#1821: https://github.com/robotframework/SeleniumLibrary/issues/1821 +.. _#1872: https://github.com/robotframework/SeleniumLibrary/issues/1872 diff --git a/docs/SeleniumLibrary-6.2.0rc1.html b/docs/SeleniumLibrary-6.2.0rc1.html new file mode 100644 index 000000000..6057aac57 --- /dev/null +++ b/docs/SeleniumLibrary-6.2.0rc1.html @@ -0,0 +1,1852 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Opening library documentation failed

+
    +
  • Verify that you have JavaScript enabled in your browser.
  • +
  • Make sure you are using a modern enough browser. If using Internet Explorer, version 11 is required.
  • +
  • Check are there messages in your browser's JavaScript error log. Please report the problem if you suspect you have encountered a bug.
  • +
+
+ + + + + + + + + + + + + + + + diff --git a/docs/SeleniumLibrary-6.2.0rc1.rst b/docs/SeleniumLibrary-6.2.0rc1.rst new file mode 100644 index 000000000..2de9c477f --- /dev/null +++ b/docs/SeleniumLibrary-6.2.0rc1.rst @@ -0,0 +1,127 @@ +======================== +SeleniumLibrary 6.2.0rc1 +======================== + + +.. default-role:: code + + +SeleniumLibrary_ is a web testing library for `Robot Framework`_ that utilizes +the Selenium_ tool internally. SeleniumLibrary 6.2.0rc1 is a new release with +compatability fixes for recent selenium versions and some bug fixes. + +All issues targeted for SeleniumLibrary v6.2.0 can be found +from the `issue tracker`_. + +If you have pip_ installed, just run + +:: + + pip install --pre --upgrade robotframework-seleniumlibrary + +to install the latest available release or use + +:: + + pip install robotframework-seleniumlibrary==6.2.0rc1 + +to install exactly this version. Alternatively you can download the source +distribution from PyPI_ and install it manually. + +SeleniumLibrary 6.2.0rc1 was released on Saturday November 18, 2023. SeleniumLibrary supports +Python 3.8 through 3.11, Selenium 4.12.0 through 4.15.2 and +Robot Framework 5.0.1 and 6.1.1. + +.. _Robot Framework: http://robotframework.org +.. _SeleniumLibrary: https://github.com/robotframework/SeleniumLibrary +.. _Selenium: http://seleniumhq.org +.. _pip: http://pip-installer.org +.. _PyPI: https://pypi.python.org/pypi/robotframework-seleniumlibrary +.. _issue tracker: https://github.com/robotframework/SeleniumLibrary/issues?q=milestone%3Av6.2.0 + + +.. contents:: + :depth: 2 + :local: + +Most important enhancements +=========================== + +- Remove deprecated headless option for chrome and firefox. (`#1858`_, rc 1) + If one specified either `headlesschrome` or `headlessfirefox` as the browser within the + Open Browser keyword, then the library would handle setting this option with the underlying + Selenium driver. But the methods to do so were depracted and then removed in Selenium + v4.13.0. Thus one was not getting a headless browser in these instances. This resolves that + issue. + +- Resolve issue with service log_path now log_output. (`#1870`_, rc 1) + Selenium changed the arguments for the service log within v4.13.0. This change allows for a + seamless usage across versions before and after v4.13.0. + +- Execute JavaScript converts arguments to strings with robot==6.1 (`#1843`_, rc 1) + If any ARGUMENTS were passed into either the `Execute Javascript` or `Execute Async Javascript` + then they were converted to strings even if they were of some other type. This has been + corrected within this release. + +Acknowledgements +================ + +I want to thank the following for helping to get out this release, + +- `René Rohner `_ for pointing out that Create Webdriver had a + mutable default value (`#1817`_) +- `Kieran Trautwein `_ for resolving the issue with + deprecated headless option for chrome and firefox. (`#1858`_, rc 1) +- `Nicholas Bollweg `_ for assisting in resolving the issue + with service log_path now log_output. (`#1870`_, rc 1) +- `Igor Kozyrenko `_ for reporting the argument issue with Execute + JavaScript and `René Rohner `_for resolving it. (`#1843`_, rc 1) +- `Robin Matz `_ for improving the documentation on page load + timeout (`#1821`_, rc 1) + +and **Yuri Verweij, Lisa Crispin, and Tatu Aalto**. + +Full list of fixes and enhancements +=================================== + +.. list-table:: + :header-rows: 1 + + * - ID + - Type + - Priority + - Summary + - Added + * - `#1817`_ + - bug + - critical + - Create Webdriver has mutable default value + - rc�1 + * - `#1858`_ + - bug + - critical + - Remove deprecated headless option for chrome and firefox. + - rc�1 + * - `#1870`_ + - bug + - critical + - Resolve issue with service log_path now log_output. + - rc�1 + * - `#1843`_ + - bug + - high + - Execute JavaScript converts arguments to strings with robot==6.1 + - rc�1 + * - `#1821`_ + - enhancement + - medium + - Improve documentation on page load timeout + - rc�1 + +Altogether 5 issues. View on the `issue tracker `__. + +.. _#1817: https://github.com/robotframework/SeleniumLibrary/issues/1817 +.. _#1858: https://github.com/robotframework/SeleniumLibrary/issues/1858 +.. _#1870: https://github.com/robotframework/SeleniumLibrary/issues/1870 +.. _#1843: https://github.com/robotframework/SeleniumLibrary/issues/1843 +.. _#1821: https://github.com/robotframework/SeleniumLibrary/issues/1821 diff --git a/docs/SeleniumLibrary.html b/docs/SeleniumLibrary.html index 856f1d547..00db82f92 100644 --- a/docs/SeleniumLibrary.html +++ b/docs/SeleniumLibrary.html @@ -1181,7 +1181,7 @@ jQuery.extend({highlight:function(e,t,n,r){if(e.nodeType===3){var i=e.data.match(t);if(i){var s=document.createElement(n||"span");s.className=r||"highlight";var o=e.splitText(i.index);o.splitText(i[0].length);var u=o.cloneNode(true);s.appendChild(u);o.parentNode.replaceChild(s,o);return 1}}else if(e.nodeType===1&&e.childNodes&&!/(script|style)/i.test(e.tagName)&&!(e.tagName===n.toUpperCase()&&e.className===r)){for(var a=0;a