Releases: ElSnoMan/pyleniumio
Remove selenium-wire
v1.21.0 - 2024.05.24
selenium-wire
is no longer maintained and has been causing multiple issues for users, so removing it was the cleanest and simplest solution.
It provided some functionality like inspecting network requests, but I'm sure there are other, better ways we can replicate that functionality if people really need it.
Changes
- Remove
selenium-wire
as a dependency - Remove anywhere it was used or referenced including:
webdriver_factory
pylenium.json
conftest.py
- docs.pylenium.io
Considerations
- After updating to
v1.21.x
, make sure to remove theseleniumwire*
values in yourpylenium.json
files
Shoutouts 🎉
Thank you to everyone that was involved in reporting this issue #329
Replace webdriver-manager with Selenium Manager
v1.20.0 - 2023.9.01
The goal of this release was to replace webdriver-manager
, which was having issues with Chrome 115, with Selenium's new Selenium Manager
👏🏽
These changes were "under the hood", so things should just continue to work without you having to do anything. However, I highly recommend reading Selenium's documentation about how to use Selenium Manager: https://www.selenium.dev/blog/2023/whats-new-in-selenium-manager-with-selenium-4.11.0/
Changes
- Replace
webdriver-manager
with the new, officialSelenium Manager
. This fixes the Chrome 115 issues 🎉 driver.version
has been removed frompylenium.json
- Selenium Manager uses the installed browser(s) to determine which driver binaries to use
- For example, if you have Chrome 116 installed, it will automatically make sure to use driver 116
- Updated package version constraints. For example,
selenium = "^4.11.2"
Considerations
- You can still use
driver.local_path
if you want Selenium Manager to use a locally installed driver instead of downloading and caching from the internet - Just upgrade to the latest Pylenium version and you should be good to go with these changes and fixes 🎉
Update Package Dependencies
v1.19.0 - 2023.06.21
Short and sweet release that focused on updating Pylenium dependencies. This is a minor version bump because there is a breaking change, but these are the highlights you will care about:
- Updated multiple packages to their newer versions: #305
- Pylenium now has a minimum Python version requirement of
3.8.1
or higher
💡So, make sure to update your Python version if you're still using
3.7.x
👍🏽
Contributers 🎉
Thank you, @LostInDarkMath, for taking the time to create this PR and making Pylenium better 🙏🏽
Better control of WebDrivers
v1.18.0 - 2023.06.17
- Make webdriver version optional by @rnestler in #299
- Bug fixes including Browser Version and SeleniumWire flag by @ElSnoMan in #302
Highlights 💡
This release focused on making improvements to our webdriver_factory.py
which uses webdriver_manager
under the hood:
pylenium.json
now hasdriver.version: null
by default. This means that Pylenium will use the driver on the PATH, if any, or default to using the latest version. This should solve most problems people were experiencing with driver versions 👍🏽pylenium.json
now hasdriver.seleniumwire_enabled: false
by default. This new flag allows you to use a regular WebDriver or a SeleniumWire Webdriver. Some people have reported issues related to SeleniumWire, so we wanted users to have the ability to "opt in" to using it if they wanted 👍🏽- Report Portal Integration removed 😮 - I like Report Portal, but keeping it up to date natively was proving more work than the value it provided. Only Allure is "natively" supported now, but remember:
💡Users can always add the integration themselves if they would like since using plugins and extending Pylenium is easy 👍🏽
Chores 🧹
These have no effect on users of Pylenium, but contributors will appreciate these improvements! 😄
- Do not install another flake8 version in CI by @rnestler in #300
- Add typer and remove rich-click by @ElSnoMan in #304
- Finally removed
setup.py
🎉 - Now we exclusively usepyproject.toml
and use pypi's OICD to publish to pypi!
Fixes 🐛
Contributers 🙇🏽♂️
As always, thank you so much for those of you who are using Pylenium, but also opening issues, having discussions, and especially for submitting PRs! Y'all are the real MVPs 👏🏽 🎉
Full Changelog: v1.17.0...v1.18.0
Add Allure Reporting
v1.17.2 - 2022.10.26
Overview
💡 Contributing to Pylenium is even easier now that you can use Gitpod - by @ElSnoMan in #290
- Add ability to pass
local_path
via CLI arg by @vincent-olivert-riera in #285 - Add allure reporting and update logging by @ElSnoMan in #291
- Add
pyc
andpys
fixtures by @ElSnoMan in #293
See the Details section below for... well, more details 😄
Fixes
- 🐛 That pesky
webdriver_manager
bug has been resolved (#278) - 👕 pylint fixes by @marksmayo in #288
Documentation
- 📝 Github Repo README updated to include the crucial
$ pylenium init
step (#283) - 📝 Viewport configuration docs updated to show how to use viewport settings (#282)
Details
The major update for version 1.17
is the native integration with Allure for test reporting and the addition of the pys
and pyc
fixtures.
Allure Reporting
Currently, Pylenium integrates natively with ReportPortal.io which is free and open source, but is relatively complex to setup and use. I wanted a simpler reporting tool that still had rich reporting; enter Allure and their pytest plugin
In three easy steps you can leverage their awesome reporting! We also added some convenient CLI commands to help with this, although using allure
directly is recommended:
-
Install allure CLI
- You can use
pylenium allure install
- or visit their docs for your machine's appropriate installation instructions (recommended)
- then you can check the installation with
pylenium allure check
- You can use
-
Run tests
- It's just pytest, but now add where you want the allure results to be saved:
pytest --alluredir=allure-report
- It's just pytest, but now add where you want the allure results to be saved:
-
Then serve the results to generate a beautiful report in your browser!
- You can use
pylenium allure serve --folder allure-report
- or
allure serve allure-report
(recommended)
- You can use
Session- and class-scoped Pylenium instances
When writing automated tests, it's recommended that each test be atomic and independent - meaning that Test B
should not be reliant on Test A
. This is a good principle to follow and enables things like running tests in parallel, but there are times when you want a single Pylenium instance for a session or for a group of tests in a Test Class.
This is what the
pys
andpyc
fixtures are for!
-
The recommended
py
fixture is an instance of Pylenium for each test function which also comes withpy_config
which is the configuration for each test functionfrom pylenium.driver import Pylenium def test_function(py: Pylenium): py.visit("https://qap.dev") ...
-
pys
andpys_config
are used if you want a single Pylenium instance for the entire Test Sessionfrom pylenium.driver import Pylenium def test_a(pys: Pylenium): py.visit("https://qap.dev") ... def test_b(pys: Pylenium): # uses same Pylenium instance as test_a ...
-
pyc
andpyc_config
are used if you want a single Pylenium instance for an entire Test Classfrom pylenium.driver import Pylenium class TestClass: def test_a(self, pyc: Pylenium): py.visit("https://qap.dev") ... def test_b(self, pyc: Pylenium): # uses same Pylenium instance as test_a ...
💡 Using
py
is highly recommended, but now you have more options for your context 💪🏽
New Contributors 🎉
As always, a big THANK YOU to everyone that uses and contributes to Pylenium! Y'all are amazing 👏🏽
- @vincent-olivert-riera made their first contribution in #285
- @marksmayo made their first contribution in #288
Full Changelog: v1.16.0...v1.17.0
Pass in any pylenium.json file when running tests
v1.16.0 - 2022.07.05
pylenium.json
[#267]
The major update for this release is the ability to pass in any pylenium.json
config file when executing your tests! Before v1.16.0, there was only a single pylenium.json
file that existed at your Project Root (after running $ pylenium init
) and this was the main config file to change.
💡 Now you can keep multiple versions of the file and use the one you need (see the Example below 👀 ⬇️
Example
You can keep different versions stored at your Project Root or in a separate folder.
Keep things at the Project Root...
📂 Project
📃 conftest.py
📃 pylenium.json
📃 local.pylenium.json
...
or put your custom ones in a different folder.
Keep the original
pylenium.json
at the Project Root so the default behavior continues to work 😉
📂 Project
📃 conftest.py
📃 pylenium.json
📂 config
📃 local.pylenium.json
📃 dev.pylenium.json
📃 stage.config.json
💡 You can name your custom Pylenium config files whatever you like, but they MUST be
.json
and have the same shape (aka schema) as the defaultpylenium.json
Finally, when you execute the tests, you can pass in which Pylenium config file to use for that run using the --pylenium_json
argument:
pytest --pylenium_json="local.pylenium.json"
pytest --pylenium_json="config/dev.pylenium.json"
Updated Logging
[#206]
The other big change was around using rich-click
(which is a combination of the rich
and click
packages) for cleaner and prettier logging and printing. With this change, a few other things were added:
- Two new, custom Log Levels:
COMMAND
andUSER
- A global, Pylenium Logger instance that can be used by the User if they choose
Log Levels
Name | Level | |
CRITICAL | 50 | |
ERROR | 40 | |
WARNING | 30 | |
USER | 25 | new |
INFO | 20 | |
COMMAND (new and default) | 15 | new, default |
DEBUG | 10 |
If you are familiar with logging, then the above table is straightforward. If not, then all you really need to know about these levels is that you can set the Log Level when executing tests, and any logs at the specified level or higher will be captured.
For example, if you wanted to set the Log Level to see only logs at INFO
and higher, you would do this:
pytest --log-cli-level=INFO
💡 The above command would ignore logs below the
INFO
level. In other words, ignore theCOMMAND
andDEBUG
logs.
COMMAND Level
The COMMAND
Log Level is used by Pylenium for logging its commands in a cleaner and easier to parse format. You shouldn't use this level unless you really want to. Take a look at our visit()
command to see it in action:
def visit(self, url: str) -> "Pylenium":
"""Navigate to the given URL.
Returns:
The current instance of Pylenium
"""
log.command("py.visit() - Visit URL: `%s`", url)
self.webdriver.get(url)
return self
💡 Notice how the string uses the
%s
format and NOT the f-string format. This is intentional!
USER Level
The USER
Log Level is meant for you! This is a convenient way for logging things if you don't want everything from the INFO
level.
💡 I highly recommend creating your own loggers, but sometimes something simple like this is all you need 😄
To take advantage of this level, use log.this()
:
# You can import this in any file
from pylenium.log import logger as log
# Log this
def add_to_cart(item: str, quantity: int):
log.this("Adding %s %s to my cart", quantity, item)
...
# Then call the function
add_to_cart("Charizard", 3)
>>> USER Adding 3 Charizard to my cart
You can also directly use py.log
:
# Log this
def add_to_cart(py: Pylenium, item: str, quantity: int):
py.log.this("Adding %s %s to my cart", quantity, item)
...
# Then call the function
add_to_cart(py, "Charizard", 3)
>>> USER Adding 3 Charizard to my cart
Other Changes
Performance Improvements
v1.15.2 - 2022.04.07
HUGE shout out to @rnestler 🙏🏽 for putting the time and energy into looking through issues, code, etc., and identifying places of improvement. Then actually submitting PRs for them! You're awesome and I really appreciate your contributions 🚀
Core functionality hasn't changed, but these are great improvements for a faster, more robust Pylenium experience.
If you're interested in more details, check out the PR issues below:
Integrate Selenium Wire for Chrome and Firefox
v1.15.0 - 2022.03.30
Overview
Selenium-Wire was proposed by Discussion #239. I was exploring this as an option and saw that we would be able to integrate with a few changes across PyleniumConfig
and webdriver_factory
.
What is Selenium-Wire?
From their GitHub page:
Selenium Wire extends Selenium's Python bindings to give you access to the underlying requests made by the browser. You author your code in the same way as you do with Selenium, but you get extra APIs for inspecting requests and responses and making changes to them on the fly.
Now you can use it with Pylenium!
The good news is that it's been integrated! 🎉 The bad news of the current implementation is that the Pylenium
class is unaware if it's using a selenium-wire driver, so it provides no autocomplete or intellisense. We need to find a way to provide the correct type hinting so we do provide autocomplete for our users.
For example, if you set the browser to "chrome"
, you will get a selenium-wire driver and can do something like this:
# Go to the Google home page
py.visit("https://google.com")
# Access requests via the `requests` attribute
for request in py.webdriver.requests:
if request.response:
print(
request.url,
request.response.status_code,
request.response.headers['Content-Type']
)
but when you type py.webdriver.
, you won't see requests
as an available option even though it does exist and works.
Known Issues
- No intellisense or autocomplete as shown in the example above
- Selenium-Wire only works for local Chrome and Firefox drivers. Remote is not yet supported
selenium-wire has a lot of power and configuration, so make sure you refer to their docs for more details.
Add
pylenium.json
now has a seleniumwire_options
field where you can set specific wire options! Refer to selenium-wire docs for more details and examples about their options.
Fixes
WebDriverManager needed to be updated to the latest because their older versions are broken for different browsers, especially with Selenium 4.
Use new Service objects for Chrome and Firefox Drivers
v1.14.3 - 2022.03.28
Overview
Thank you all for the great feedback. There were deprecations warnings and some bugs from our migration to Selenium 4. This minor release should fix them! There shouldn't be any more warnings, but please create an Issue with anything else 🙇🏽♂️
Changes
- #241 We removed the deprecated DesiredCapabilities from multiple browsers in
webdriver_factory.py
, but we didn't replace them with the newOptions
approach. This is now fixed! - Chrome and Firefox raised warnings about the deprecated
executable_path
argument. These have been removed and replaced with their corresponding Service objects.
Fix Firefox Instantiation
v1.14.2 - 2022.03.23
Overview
Firefox was raising issues when instantiating using our webdriver_factory
. That is fixed now! 🎉