pveltrop / pyrunner
Python/Selenium testrunner
This package's canonical repository appears to be gone and the package has been frozen as a result.
Installs: 2 717
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
Language:Python
This package is auto-updated.
Last update: 2021-07-08 19:42:05 UTC
README
About PyRunner
Pyrunner is a python package, which can run browser tests for Laravel applications. Pyrunner currently features:
- Interactively develop browser tests with the development mode
- Log and make screenshots of each step
- Retry failed test automatically as many times as you want
- Easy to use in CICD, less prone to crashes than Laravel Dusk
Usage
Install Python: https://www.python.org/downloads/release/python-381/
Install Pip: https://pip.pypa.io/en/stable/installing/
Go to the root of your project.
Install this package:
composer require pveltrop/pyrunner:dev-master#(commit)
Then install PyRunner in your Laravel project:
php artisan pyrunner:install
Prepare your (test) database:
php artisan migrate:fresh --seed (--database=mysql_testing)
Launch PyRunner in a new terminal:
php artisan pyrunner:start (--dev) (--debug) (--shell) (--screenshots)
Launch PyRunner in your active terminal:
python vendor/pveltrop/pyrunner/test_app.py (--dev) (--debug) (--shell) (--screenshots)
Parameters
Development (--dev)
php artisan pyrunner:start --dev
Launches the app and inserts a breakpoint. Meaning you get an interactive terminal, so you can test browser commands, or run a test individually.
Keep in mind:
Development mode will insert a breakpoint at launch, so you can run whatever you want in your _tests.py file.
ipdb>
So if you want to run the fake function in _tests.py, you run fake().name() (for example):
ipdb> fake.email()
'siennaschiffer@van.com'
If you want to run all tests, and insert a breakpoint if it fails anywhere (your test code will be reloaded every time):
ipdb> RunTests()
If you want to re-run a single test, first literally enter:
ipdb> reload(tests)
This will reload your _tests.py file. Then:
ipdb> tests.nameoftest()
Debug (--debug)
php artisan pyrunner:start --debug
This option will enable more specific output during test command executions. This can be helpful to pinpoint where PyRunner is struggling.
Screenshots (--screenshots)
php artisan pyrunner:start --screenshots
This option will enable screenshots. Screenshots will be made whenever you define a new step (pr.step()).
ENV
php artisan pyrunner:env
This option will generate a .env.example and .env.testing. Change values you want or dont want in version control.
Configure for Laravel
Make sure your APP_URL is set correctly, to the same address as you use locally.
- Make a .env.testing file, for local and GitLab testing, if you skipped this step during php artisan pyrunner:install
php artisan pyrunner:env
If this environment doesn't work locally, it won't work on GitLab either.
- IMPORTANT: set TELESCOPE_ENABLED=false, otherwise migrations wont work currently
Optional if you want to receive testresults in Slack or Pushbullet:
- On GitLab, go to Settings -> CI/CD -> Variables
- Define a SLACK variable which is the url for the webhook you want to use
- Define a PUSHBULLET variable which contains the API key of your Pushbullet account
- For pushbullet: also pass a GitLab variable in the yml file with parameter: --pbchannel=channelName
Optional if you want to host a GitLab runner yourself:
- Install GitLab runner on a pc and link it to your project repository in CI/CD
- Install docker on this PC, and pull the image you built earlier:
docker pull registry.gitlab.com/(group)/(repository)
Writing tests
- Define test functions in _tests.py (in your project root) with this structure:
# -----------------------------------------------------------
# Tests
# -----------------------------------------------------------
def users_can_login():
pr.start('Users Can Login') # Prints start of test
pr.step('Logout first') # Prints current step being executed
pr.browser.get('http://localhost/_testing/pylogout') # Redirecting browser
pr.step('Enter email')
pr.type_xpath('//*[@id="email"]', pyUserEmail) # Typing in a field
pr.step('Enter password')
pr.type_xpath('//*[@id="password"]', pyUserPassword)
pr.step('Login')
pr.click('//*[@id="kt_login_signin_submit"]','#kt_login_signin_submit','kt_login_signin_submit') # Click function has 3 parameters. The order is: Xpath selector, CSS selector, ID selector. Send atleast one.
pr.end('Users Can Login') # Prints end of test
# -----------------------------------------------------------
# End of tests
# -----------------------------------------------------------
- Define refactoring functions with this structure:
# -----------------------------------------------------------
# Refactoring/scanning
# -----------------------------------------------------------
def scan_for_dd():
pr.start('Check if all dd() is removed from code')
pr.step('Scan files with RegEx')
pr.scan_regex(r"dd\([\',\"].*[\',\"]\)")
pr.end('Check if all dd() is removed from code')
# -----------------------------------------------------------
# End of refactoring
# -----------------------------------------------------------
Test Commands
pr.click(xpath,css,id)
The parameters are selectors for HTML elements. (right click in Chrome/Firefox) All three are optional, but the more you use, the more likely the click will succeed.
pr.switch_tab(index)
Switch the browser to the provided index.
Selecting
pr.select_value_name(name, value)
Select an option in an HTML element, by value.
pr.select_index_name(name, index)
Select an option in an HTML element, by index.
pr.select_value_id(id, value)
Select an option in an HTML element, by value.
pr.select_index_id(id, index)
Select an option in an HTML element, by value.
pr.find_text(text)
Find text on the current page.
pr.find_id(id)
Try to find a VISIBLE element by ID.
pr.find_class(class)
Try to find a VISIBLE element by Class.
pr.find_css(css)
Try to find a VISIBLE element by CSS selector.
pr.find_name(name)
Try to find a VISIBLE element by Name.
pr.find_xpath(xpath)
Try to find a VISIBLE element by Xpath.
Typing
pr.type_xpath(xpath)
Try to type in an element selected by xpath.
pr.type_name(name)
Try to type in an element selected by name.
pr.type_id(id)
Try to type in an element selected by id.
pr.type_css(css)
Try to type in an element selected by css.
pr.change_text_xpath(xpath)
Try to clear and type text in an element selected by xpath.
pr.change_text_name(name)
Try to clear and type text in an element selected by name.
pr.change_text_id(id)
Try to clear and type text in an element selected by id.
pr.change_text_css(css)
Try to clear and type text in an element selected by css.
Docker Image
Preparing the Docker image
- Build a docker image for your project
- Navigate to the Docker folder in this repo
- Copy and paste the following files from your project to this folder, to speed up CI/CD:
composer.json
composer.lock
package.json
package-lock.json
- docker login registry.gitlab.com
- docker build -t registry.gitlab.com/(group)/(repository) .
- docker push registry.gitlab.com/(group)/(repository)
- Update the Docker image being used in .gitlab-ci.yml