spyoungtech / behave-webdriver Goto Github PK
View Code? Open in Web Editor NEWSelenium webdriver step library for use with the behave BDD testing framework
License: MIT License
Selenium webdriver step library for use with the behave BDD testing framework
License: MIT License
Got around to testing remote driver with selenium hub. Noticed a lot of the wait
feature tests fail with an element not found type of exception.
This may or may not be something that can be helped.
Currently, there are only constructors for chromedriver variations.
Should provide, at a minimum, basic constructors for Firefox, PhantomJS, and Safari.
All the core features are now present. Just going to do some cleanup and documentation, then we'll tag and push to PyPI. Hope to get this done in the next coming days.
List of some tasks I hope to get done here....
I'm using behave-webdriver as a part of my BDD Python testing framework. It works very well, although I have a problem with going to step declaration in PyCharm. It will be best to explain it through example. Let's say I want to use "When I move to element" step. First thing is that when I want to use this sentence and I use PyCharm autocomplete it is autocompleted as
When I move to element "{element}"
This sentence is not recognizable by PyCharm autocomplete. I can fix it by removing backslashes:
When I move to element "{element}"
This one IS visible by PyCharm. I can use "go to declaration".
But, when I change variable element to any other name than "element" than again "go to declaration" is not working, e.g.:
When I move to element "{some_element}"
Any other BDD sentences with an argument, which were written by me are working correctly (go to the declaration is working), e.g.: Some step with "example_parameter"
Are you familiar with this issue? I'm guessing that it might be PyCharm problem, not behave-webdriver.
It appears that there are two steps for "I pause for Xms" in actions.py. Can't they (the given and then when) be combined?
and
When you use "I clear the inputfiled "{element}" step with Chrome webdriver the field doesn't clears, but you can still add the contents to it.
Broken with selenium 4.0.0.
Reproduced with python 3.8.10 and 3.9.5
File "xxxxxxxxxxxx/venv/lib/python3.8/site-packages/behave_webdriver/conditions.py", line 48, in <module>
class element_is_selected(NegationMixin, EC.element_located_to_be_selected):
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
Reproducable by running package tests:
git/behave-webdriver$ python setup.py test
running test
WARNING: Testing via this command is deprecated and will be removed in a future version. Users looking for a generic test entry point independent of test runner are encouraged to use tox.
running egg_info
writing behave_webdriver.egg-info/PKG-INFO
writing dependency_links to behave_webdriver.egg-info/dependency_links.txt
writing requirements to behave_webdriver.egg-info/requires.txt
writing top-level names to behave_webdriver.egg-info/top_level.txt
reading manifest file 'behave_webdriver.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'behave_webdriver.egg-info/SOURCES.txt'
running build_ext
behave_webdriver (unittest.loader._FailedTest) ... ERROR
======================================================================
ERROR: behave_webdriver (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: behave_webdriver
Traceback (most recent call last):
File "/usr/lib/python3.8/unittest/loader.py", line 470, in _find_test_path
package = self._get_module_from_name(name)
File "/usr/lib/python3.8/unittest/loader.py", line 377, in _get_module_from_name
__import__(name)
File "/home/haavardw/git/behave-webdriver/behave_webdriver/__init__.py", line 15, in <module>
from behave_webdriver.driver import (Chrome,
File "/home/haavardw/git/behave-webdriver/behave_webdriver/driver.py", line 18, in <module>
from behave_webdriver.conditions import (element_is_present,
File "/home/haavardw/git/behave-webdriver/behave_webdriver/conditions.py", line 48, in <module>
class element_is_selected(NegationMixin, EC.element_located_to_be_selected):
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (errors=1)
Test failed: <unittest.runner.TextTestResult run=1 errors=1 failures=0>
error: Test failed: <unittest.runner.TextTestResult run=1 errors=1 failures=0>
Adding firefox to tests (per #12 ) reveals that Firefox fails some existing tests.
Failing scenarios:
tests/features/attribute.feature:14 The CSS attribute "color" of a element should be "red"
tests/features/click.feature:18 Double click on the button #toggleMessage should display another message
tests/features/click.feature:26 Double click on the element #toggleBackground should make the elemnt blue
tests/features/moveTo.feature:11 Move to just the element
tests/features/moveTo.feature:22 Move to the element with a too large offset
tests/features/sampleSnippets.feature:30 double click on a button
tests/features/sampleSnippets.feature:66 submit form
tests/features/sampleSnippets.feature:130 check css attribut
15 features passed, 4 failed, 0 skipped
82 scenarios passed, 8 failed, 0 skipped
305 steps passed, 8 failed, 7 skipped, 0 undefined
Took 0m29.201s
Failing scenarios:
Scenarios still needed to pass to put this into standard features
tests\experimental-features\drag.feature:13 Drag to dropzone
This is likely related to element position issues.
Test output
Scenario: Drag to dropzone # tests\experimental-features\drag.feature:13
Given I open the site "/" # behave_webdriver\steps\given.py:15
And I have a screen that is 1024 by 768 pixels # behave_webdriver\steps\given.py:199
When I scroll to element "#draggable" # behave_webdriver\steps\when.py:97
Then I expect that element "#draggable" is positioned at 42px on the x axis # behave_webdriver\steps\then.py:199
Assertion Failed: Position was 34 on the x axis
I want to set the preferences for the firefox_profile in wedriver.Firefox(firefox_profile=).
Where and how do i incorporate it into the framework ?
Chromedriver v2.33 is no longer working with the latest version of selenium, causing the CI build to fail
The chromedriver should be updated to version 2.35.
There is a problem that, due to some upstream issues, values that webdrivers return for CSS values may be different based on what webdriver is being used.
One key issue is that, when getting the value of CSS attributes that are rgb/rgba values, Selenium presents them with spaces between the commas, even though the browser does not.
For example, when getting the 'color' attribute an element like <span style="color: rgb(255,0,0)">text</span>
will be reported by selenium as 'rgb(255, 0, 0)'
this will cause string-based matching to fail for example if you have a step that says I expect that the css attribute "color" from element ".red" is "rgb(255,0,0)"
even though the value is, in fact, rgb(255,0,0)
in the DOM, selenium reports the string with spaces, so the assertion using plain text matching will fail.
Additionally, based on what webdriver you happen to be using, when a CSS color value is defined as rgba with an Alpha of 1
, (eg. rgba(r,b,g,1)
) the string selenium will return will be 'rgb(r, b, g)
rather than rgba(r, b, g, 1)
. When the alpha is any value other than 1
, selenium properly returns the value as rgba. This problem has been seen exhibited in at least Firefox. Chrome and PhantomJS don't seem to produce this particular facet of the issue.
modals feature requires implementation
tests\experimental-features\modals.feature:9 Test if alert is opened accepted
tests\experimental-features\modals.feature:17 Test if alert is opened & dismissed
tests\experimental-features\modals.feature:24 Test if confirm is canceled
tests\experimental-features\modals.feature:34 Test if confirm is accepted
tests\experimental-features\modals.feature:43 Test if prompt is opened & dismissed
tests\experimental-features\modals.feature:53 Test if prompt is accepted
tests\experimental-features\modals.feature:62 Test if prompt has text entered
Hi,
Does the current version of the project supports finding multiple elements at once and returning it as a list or array of web elements?
I found this Select class (https://github.com/spyoungtech/behave-webdriver/blob/master/behave_webdriver/driver.py#L26-L38) and thought it might be the implementation but I can't get it to work. Kindly give example implementation if indeed this is the support for finding multiple elements.
Some steps contain exactly the same logic. Instead of repeating the logic, this should be refactored. For example
@then('I expect that element "([^"]*)?"( not)* matches the text "([^"]*)?"')
Contains the same logic as
@given('the element "([^"]*)?"( not)* matches the text "([^"]*)?"')
It would be ideal if instead, we did something like
@then('I expect that element "([^"]*)?"( not)* matches the text "([^"]*)?"')
@given('the element "([^"]*)?"( not)* matches the text "([^"]*)?"')
def check_element_matches_text(context, element, negative, text):
# logic
These are the 6 redundancies identified by Better Code Hub. They are all between given.py
and then.py
Wait feature tests are failing. BehaveDriver.wait_for_element_condition
will need some serious reworking.
Appears to be some issues with detecting element position on the x/y axes. Not sure the root cause.
Failing scenarios
tests\experimental-features\elementPosition.feature:12 The element #square100x100 is at XX pixels on the X axis
tests\experimental-features\elementPosition.feature:16 The element #square100x100 is at XX pixels on the Y axis
Test output for failing scenarios
Scenario: The element #square100x100 is at XX pixels on the X axis # tests\experimental-features\elementPosition.feature:12
Given I open the site "/" # behave_webdriver\steps\given.py:15
And I have a screen that is 800 by 600 pixels # behave_webdriver\steps\given.py:199
And the element "#square100x100" is 100px broad # behave_webdriver\steps\given.py:177
And the element "#square100x100" is 100px tall # behave_webdriver\steps\given.py:177
When I scroll to element "#square100x100" # behave_webdriver\steps\when.py:97
Then I expect that element "#square100x100" is positioned at 40px on the x axis # behave_webdriver\steps\then.py:199
Assertion Failed: Position was 32 on the x axis
@Pending
Scenario: The element #square100x100 is at XX pixels on the Y axis # tests\experimental-features\elementPosition.feature:16
Given I open the site "/" # behave_webdriver\steps\given.py:15
And I have a screen that is 800 by 600 pixels # behave_webdriver\steps\given.py:199
And the element "#square100x100" is 100px broad # behave_webdriver\steps\given.py:177
And the element "#square100x100" is 100px tall # behave_webdriver\steps\given.py:177
When I scroll to element "#square100x100" # behave_webdriver\steps\when.py:97
Then I expect that element "#square100x100" is positioned at 843px on the y axis # behave_webdriver\steps\then.py:199
Assertion Failed: Position was 1084 on the y axis
Hi, I am writing Behave based framework. I wish to know what happens under the hood such that feature file can re-use step files and can able to call behave-webdriver steps without any implementation as mentioned in https://behave-webdriver.readthedocs.io/en/stable/quickstart.html#importing-the-step-implementations
How can we import steps in feature file in Behave.
Adding Safari to tests (per #12 ) reveals that Safari fails some existing tests.
In light of this, combined with failing firefox tests ( #14 ), to ease the burden of identifying the core issues, #10 is a high priority
Failing scenarios:
tests/features/attribute.feature:14 The CSS attribute "color" of a element should be "red"
tests/features/click.feature:13 Single click on the button #toggleMessage should display an message
tests/features/click.feature:18 Double click on the button #toggleMessage should display another message
tests/features/cookie.feature:28 The cookie "test3" should be created
tests/features/cookie.feature:34 The cookie "test3" should be deletable
tests/features/elementSize.feature:8 The element #square100x100 whould have a width of 100px
tests/features/elementSize.feature:14 The element #square100x100 whould not have a width of 101px
tests/features/form.feature:8 Test if a message is shown when the form is submitted
tests/features/moveTo.feature:11 Move to just the element
tests/features/sampleSnippets.feature:18 click on link
tests/features/sampleSnippets.feature:24 click on button
tests/features/sampleSnippets.feature:30 double click on a button
tests/features/sampleSnippets.feature:36 click on element
tests/features/sampleSnippets.feature:42 add value to an input element
tests/features/sampleSnippets.feature:60 drag n drop
tests/features/sampleSnippets.feature:66 submit form
tests/features/sampleSnippets.feature:72 wait for element
tests/features/sampleSnippets.feature:77 wait for element using default wait time
tests/features/sampleSnippets.feature:82 pause
tests/features/sampleSnippets.feature:95 check visibility
tests/features/sampleSnippets.feature:130 check css attribut
tests/features/sampleSnippets.feature:161 check selected
tests/features/sampleSnippets.feature:169 set / read cookie
tests/features/sampleSnippets.feature:179 delete cookie
tests/features/sctructure.feature:8 Test if the page has a H1 I expect its at the top of the page
11 features passed, 8 failed, 0 skipped
65 scenarios passed, 25 failed, 0 skipped
268 steps passed, 25 failed, 27 skipped, 0 undefined
Took 0m25.831s
Window features need implementation.
Use the following feature and test in Safari
Given I open the url "https://behave-webdriver.readthedocs.io/en/latest/steps.html"
When I click on the link "Read the Docs"
When I pause for 2000ms
Then I expect that element "h1" contains the text "Read the Docs"
It shows a success that it clicked on the link, but watching it, it doesn't navigate to the link. Thus the final "Then" statement fails
Given I open the url "https://behave-webdriver.readthedocs.io/en/latest/steps.html" # venv/lib/python3.7/site-packages/behave_webdriver/steps/actions_re.py:60 1.128s
When I click on the link "Read the Docs" # venv/lib/python3.7/site-packages/behave_webdriver/steps/actions.py:31 0.050s
When I pause for 2000ms # venv/lib/python3.7/site-packages/behave_webdriver/steps/actions.py:16 2.003s
Then I expect that element "h1" contains the text "Read the Docs" # venv/lib/python3.7/site-packages/behave_webdriver/steps/expectations.py:121 0.014s
Assertion Failed: Element text does not contain "Read the Docs"
Shadow-dom is very hard to test and to find elements.
find_element_XXX
methods cannot pass through shadow-root and therefore great deal of effort should be done to reach some element if nested shadow elements are in the path.
It is also difficult to wait for some element to appear or desappear for the same reason.
driver.execute_script('return arguments[0].shadowRoot', element)
is enough to reach the shadow-dom of an element and from there, any other find_element_XXX
method will work (until reaching another shadow dom of course)
Proposition to ease usage:
that splits the css selector or xpath expression to get the shadow-dom of a element and continue descending in the selection.
Rough example:
def shadow(driver, element):
driver.execute_script('return arguments[0].shadowRoot', element)
def find_element_by_css_selector(driver, selector):
shadow_dom_selector = '> ##shadow-dom'
selectors = selector.split(shadow_dom_selector)
element = None
for s in selectors:
if element:
element = shadow(element)
else:
element = driver
element = element.find_element_by_css_selector(s)
return element
tata = find_element_by_css_selector(driver, 'div.foo bar > ##shadow-dom baz.toto > #titi > ##shadow-dom tata')
What do you think?
I'm attempting to use this in Python 2.7 on a Mac. I installed behave and behave-webdriver via pip.
examples $ cd minimal-project/
minimal-project $ behave
Exception ImportError: cannot import name BehaveDriver
Traceback (most recent call last):
File "/usr/local/bin/behave", line 11, in <module>
sys.exit(main())
File "/usr/local/lib/python2.7/site-packages/behave/__main__.py", line 183, in main
return run_behave(config)
File "/usr/local/lib/python2.7/site-packages/behave/__main__.py", line 127, in run_behave
failed = runner.run()
File "/usr/local/lib/python2.7/site-packages/behave/runner.py", line 804, in run
return self.run_with_paths()
File "/usr/local/lib/python2.7/site-packages/behave/runner.py", line 808, in run_with_paths
self.load_hooks()
File "/usr/local/lib/python2.7/site-packages/behave/runner.py", line 784, in load_hooks
exec_file(hooks_path, self.hooks)
File "/usr/local/lib/python2.7/site-packages/behave/runner_util.py", line 386, in exec_file
exec(code, globals_, locals_)
File "features/environment.py", line 1, in <module>
from behave_webdriver import BehaveDriver
ImportError: cannot import name BehaveDriver
Hi, all,
I'm a QA, When I find your the project, I so surprise, so good project.
I am using python+appium+behave, And when I use the Class:
conditions.element_contains_value, like this:
conditions.element_contains_value((MobileBy.IOS_PREDICATE, "name = 'login'"), text_='login')(context.behave_driver)
I get an Exception:
selenium.common.exceptions.WebDriverException: Message: Method is not implemented
But when I use class: conditions.element_contains_text, like this:
conditions.element_contains_text((MobileBy.IOS_PREDICATE, "name = 'login'"), text_='login')(context.behave_driver)
It's OK.
So Why? And how can I use the Class: conditions.element_contains_value?
Thanks a lot.
Modals feature tests not passing for phantomjs
Element focus feature requires implementations
tests\experimental-features\focus.feature:8 The element #textinput should not have the focus by default
tests\experimental-features\focus.feature:11 The element #textinput should have the focus when selected
moveTo feature failing in firefox
I don't think this is a bug as much as lack of coding experience. I'm porting over some very rudimentary lettuce_webdriver features and steps, and I'm struggling for a clean replacement for "I should see..."
One such feature line for this is:
Scenario: Testing Webdriver
When I open the url "http://my.login.page"
Then I should see "Forgot Your Password?"
Of the three definitions below, only the first one works. The latter two are not recognized and behave suggests a snippet like the first one.
@then(u'I should see "Forgot Your Password?"')
def step_impl(context):
assert context.behave_driver.element_contains('body', 'Forgot Your Password?')
@then(u'I should see "([^"]*)?"')
def step_impl(context, value):
assert context.behave_driver.element_contains('body', value)
@then(u'I should see "([^"]*)?"')
def step_impl(context, value):
context.execute_steps( u"""
then I expect that element "body" contains the text "{text}')
""").format(text = value)
I have been using normal Python and behave BDD. Today I come across this behave-webdriver and curious to know if it supports page object model.
I tried to implement it within my existing framework but seems I could not.
Your given example has almost everything like steps, features, etc but it has no page class. In page object model generally we devices logic and data. Currently, if I use your this framework. I will have to write data and login both into step class I assume.
Looking for some helpful inputs.
add appveyor build to test against IE on a Windows build
There is a bug where if a transformer class is not set, this error will occur.
Pip fails due to use of encoding
argument in setup.py
, which is not valid in Python2.
$ python2 -m pip install behave-webdriver
Collecting behave-webdriver
Downloading https://files.pythonhosted.org/packages/f7/bc/61ac3c54a823f19e98c191fcd3b922bd7eb9281086bb8eb39ec14b123f2e/behave-webdriver-0.2.0.tar.gz
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/private/var/folders/vk/1l_9vpz54bb6rhmg7twwxfyw0000gp/T/pip-install-w5AozC/behave-webdriver/setup.py", line 3, in <module>
with open('README.rst', 'rt', encoding='utf8') as f:
TypeError: 'encoding' is an invalid keyword argument for this function
See SeleniumHQ/selenium#4570 -- 'submit' for firefox is implemented via a JS shim by selenium. Because of some complexity with the page loading strategies, firefox will not wait for the subsequent page load on submission. Hence the test tests/features/sampleSnippets.feature:67 submit form
fails for firefox.
Cookie feature not passing for phantomjs -- PhantomJS doesn't like when the domain information is not present on the cookie. The error Can only set Cookies for the current domain
is presented by the driver.
Currently, only headless Google Chrome is tested in the travis CI build. The proposal is to add support for additional browsers. At a minimum, we'd like to add Firefox support, Safari and IE would be nice as well. Lastly, if it's not too much effort, we'll hope to add Opera as well.
For PhantomJS, this shouldn't be a problem as PhantomJS, like Chrome, it can run in the headless travis environment without any additional accommodations. However, Firefox and Safari may require some additional effort.
Additional details for possible solutions from this Travis article: GUI and Headless Browser Testing
Browsers passing tests
click feature fails for firefox
Provide fixtures for setup/cleanup of the driver.
window feature failing for firefox
Most assertions currently do not provide additional info when the case fails.
Ideally, according to the behave documentation, it would be ideal to use an assertion matching library, over plain ol' asserts.
Select features need implementation. Also ideal if we can support the th
, rd
, st
from the original cucumber-boilerplate project.
Tracking efforts from #60 -- possibly implement as step matcher.
See original comments for details.
The BehaveDriver
class aims to be fully substitutable for any selenium webdriver. Right now, BehaveDriver
has a driver (I.E. self.driver
) and its __getattr__
implementation alone probably only goes so far for providing substitutability. It may be better if it were the case that it is a webdriver, rather than has a webdriver.
Thinking about restructuring things, such that the BehaveDriver
class works as a mixin for Selenium's webdriver classes. One such example of this is selenium-requests. Loosely, each browser would have its own class that uses the mixin, so they can override the behaviors on a browser-basis.
Special variants would be provided as classmethods of the specific browser classes, E.g.
# behave_webdriver.Chrome
class Chrome(BehaveDriverMixin, webdriver.Chrome):
@classmethod
def headless(cls, *args, **kwargs):
chrome_options = kwargs.pop('chrome_options', None)
if chrome_options is None:
chrome_options = ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
kwargs['chrome_options'] = chrome_options
return cls(*args, **kwargs)
# invoke chromedriver with headless options
from behave_webdriver import Chrome
driver = Chrome.headless()
My thoughts are that, in addition to improving substitutability, this can assist in dealing with browser-specific issues. Additionally, I think this makes the alternate constructors somewhat more flexible. This may also ease some testing burdens.
As further thought, it may be possible to separate selenium-specific ideas from behave-specific ideas, making the selenium-based parts more reusable elsewhere. ๐ค
behave-webdriver is not only good for testing, but could probably be used for assisting (particularly for non-technical/developer roles) in automating browser tasks.
This should probably include (or reference) good documentation on using browser inspector tools.
It would be nice if we had an example of using behave-webdriver with behave-django.
When I use behave-webdriver with Python 2.7.1, then I get an error "sre_constants.error: nothing to repeat".
This is fixed in current versions of Python 2.7 and does not throw an exception anymore. See Python Issue18647.
I can not upgrade Python, because I need a special Python interpreter, which is only available for Python 2.7.1.
Replacing "([^"]*)?" by "([^"]+)?" is a compatible fix, so behave-webdriver will also work with Python 2.7.1.
I want to just include a single OSX build that will run using Safari. Might need some help with this. Having a hard time navigating the matrix includes/excludes for travis.
The biggest struggle is that I develop on Windows, so for now I'm just running through a lot of trial and error with the travis builds to try to get things right.
within viewport feature needs implementations
To give users the most flexibility, as much logic as possible should be contained in the BehaveDriver class, rather than in the step definitions.
Additionally, it would probably be useful to pass along the context to every function used as well. Similar to the behaving
implementations.
The idea is to support locating elements both by CSS selectors and xpath for all the step definitions dealing with elements.
The current logic is simple but incomplete, since it will only work if the xpath starts with //
. However, xpaths don't necessarily have to start like this. It would be ideal if we could implement a better way to differentiate xpath versus CSS selectors in locating elements.
IIRC, the way cucumer-boilerplate does this is it simply tries one first to see if a result is found, then tries another. This may be a better approach than the current method we're using now.
Also note the same logic is repeated in the wait_for_element_condition method.
This error is strange since the README and setup.py have not changed (AFAIK) since last release.
Error as seen on travis
Uploading behave_webdriver-0.3.0-py2.py3-none-any.whl
100%|โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ| 43.3k/43.3k [00:00<00:00, 70.2kB/s]
NOTE: Try --verbose to see response content.
HTTPError: 400 Client Error: The description failed to render in the default format of reStructuredText. See https://pypi.org/help/#description-content-type for more information. for url: https://upload.pypi.org/legacy/
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.