ScreenPyHQ / screenpy

Screenplay pattern base for Python automated UI test suites.
MIT License
27 stars 3 forks source link

Un-retire `screenpy-quickstart`! #52

Open perrygoy opened 1 year ago

perrygoy commented 1 year ago

It would be nifty to bring this script back! Seeing this LinkedIn article which mentions that script, i realized folks who are trying to get into this pattern probably really liked having that handy script.

We could make it pretty slick. It could check what extensions are currently installed (screenpy_selenium, screenpy_requests, etc.) and try to access a private file within them that tells screenpy what files to create in the quickstart script. Or each plugin could have its own quickstart script, but even screenpy-selenium-quickstart is getting kinda wordy...

Also make sure to be more explicit about how the file names and structure is arbitrary and can be changed to suit the user's needs whenever they want. This is more for beginners than users making their third or fourth suite.

perrygoy commented 1 year ago

After coming back to this months later, i think i have an idea using pkg_resources:

>>> import pkg_resources
>>> [pkg.project_name for pkg in pkg_resources.working_set]
[..., 'screenpy', 'screenpy-selenium', 'screenpy-adapter-allure', 'screenpy-pyotp', ...]

For each of the screenpy extensions found, the quickstart script could call extension.quickstart or something with the filepath and compose the end result with each package! I think that could work!

Edit: i just found this warning on the setuptools documentation:

Use of pkg_resources is deprecated in favor of importlib.resources, importlib.metadata and their backports (importlib_resources, importlib_metadata). Some useful APIs are also provided by packaging (e.g. requirements and version parsing). Users should refrain from new usage of pkg_resources and should work to port to importlib-based solutions.

So... i haven't found a way to do it instead scratch that, this works:

import importlib
import importlib.metadata

extension_names = [
    d.name 
    for d in importlib.metadata.distributions() 
    if d.name.startswith("screenpy-")
]

for extension_name in extension_names:
    extension = importlib.import_module(extension_name.replace("-", "_"))

I'm not sure i like this solution, but i can't find a way to get the module name to use for import_module (which uses the module name (e.g. "screenpy_selenium") and not the distribution name (e.g. "screenpy-selenium")). Since we consistently name our ScreenPy extensions with dashes in the distribution and underscores in the module, this works for now at least.

There has to be a way to get that module name, though.

perrygoy commented 1 year ago

Phew, i found something! importlib.metadata has a packages_distributions convenience method that pretty much negates the need for the stuff i was annoyed with in the previous comment. We can do this instead!

import importlib
import importlib.metadata

extension_names = [
    package
    for package in importlib.metadata.packages_distributions().keys()
    if package.startswith("screenpy_")
]

for extension_name in extension_names:
    extension = importlib.import_module(extension_name)
bandophahita commented 1 year ago

This raises an interesting question about the style of quickstart. Does it use pytest or unittest? or is it agnostic?