Coder Social home page Coder Social logo

minkextension's Introduction

Behat

Behat is a BDD framework for PHP to help you test business expectations.

Gitter chat License Build Status

Installing Behat

The easiest way to install Behat is by using Composer:

$> composer require --dev behat/behat

After that you'll be able to run Behat via:

$> vendor/bin/behat

Installing Development Version

Clone the repository and install dependencies via Composer:

$> composer install

After that you will be able to run development version of Behat via:

$> bin/behat

Contributing

Before contributing to Behat, please take a look at the CONTRIBUTING.md document.

Versioning

Starting from v3.0.0, Behat is following Semantic Versioning v2.0.0. This basically means that if all you do is implement interfaces (like this one) and use service constants (like this one), you would not have any backwards compatibility issues with Behat up until v4.0.0 (or later major) is released. Exception could be an extremely rare case where BC break is introduced as a measure to fix a serious issue.

You can read detailed guidance on what BC means in Symfony BC guide.

Useful Links

Contributors

minkextension's People

Contributors

adrienbrault avatar ciaranmcnulty avatar ckjeldgaard avatar dcsg avatar digitalkaoz avatar dunglas avatar e-weimann avatar erickwilder avatar everzet avatar gimler avatar goutte avatar khepin avatar kilip avatar kingcrunch avatar kssundarrajan avatar mauricios avatar mikaelrandy avatar newtonwagner avatar pschultz avatar relequestual avatar robocoder avatar romulodl avatar sanpii avatar shashikant86 avatar soullivaneuh avatar stfalcon avatar stof avatar swestcott avatar weaverryan avatar wouterj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

minkextension's Issues

Mink should support setting the base_url per driver

Hello,

I'm using the Goutte and Selenium2 drivers to test an application.

Since the whole application runs inside a virtual machine I need different base_urls for both drivers. Goutte runs against http://localhost where Selenium need to run the tests against http://localhost:8110/ (the redirection port of the VM). Unfortunately we've to run the tests inside the VM, since on it the only place where we can be sure we've the right PHP version and so on.

My current workaround is a to use a tagged hook:

    /**
     * Workaround for Selenium tests need to connect to a different port.
     *
     * @BeforeScenario @javascript
     */
     public function before(BeforeScenarioScope $scope)
     {
         $this->setMinkParameter(
             'base_url',
             'http://localhost:8110/'
        );
     }

Please add support for setting base_url for every driver itself.
Thanks

Exception when visiting a page which redirects to itself in Goutte

When we try to visit a page that redirects to itself, we get a huge exception in Goutte.

PHP Fatal error: Maximum function nesting level of '100' reached, aborting! in D:\behat\vendor\guzzle\guzzle\src\Guzzle\Common\Collection.php on line 95
PHP Stack trace:
.
.
.

When we run the same in Selenium, we get desired results.

Is there any way to capture a page that loops indefinitely and throw a suitable exception?

Example:
Given I am on "/about"
Cannot load the page "/about". It redirects indefinitely.

Selenium2 Driver Config: 'Proxy' capability fails when left as default value

I'm setting up a selenium grid and encounter an error when trying to run tests with chrome and chrome driver while using a selenium HUB / NODE setup.

An error occurs when running the tests against a selenium grid. The error occurs when the chrome driver expects the proxy config item in the capabilities to be omitted.

The chrome config is as follows:

default:
     paths:
         features: 'features'
         bootstrap: 'features/bootstrap'
     context:
         parameters:
             javascript_session: selenium
             browser: chrome
             show_cmd: open %s
     extensions:
         Behat\MinkExtension\Extension:
             base_url: 'http://example.co.uk/'
             default_session: selenium2
             browser_name: chrome
             selenium2:
               capabilities:
                 browserName: chrome
                 browser: chrome
                 browserVersion: 21
                 version: "21"
                 chrome:
                   switches:
                     - "--start-maximized"
                     - "--disable-translate"

As you can see no proxy is specified.

When placing the debugger at the following line:

https://github.com/Behat/MinkExtension/blob/master/src/Behat/MinkExtension/Extension.php#L36

The config variable has a value present within the capabilities array for 'proxy'. It's an empty array.

When attempting to run the test suite the following error occurs on the selenium node :

proxy must be of type dictionary, not list. Received:
Command duration or timeout: 1.02 seconds
Build info: version: '2.25.0', revision: '17482', time: '2012-07-18 21:08:56'
System info: os.name: 'Windows 7', os.arch: 'x86', os.version: '6.1', java.version: '1.6.0_31'
Driver info: driver.version: ChromeDriver

When I comment out the following lines:

https://github.com/Behat/MinkExtension/blob/master/src/Behat/MinkExtension/Extension.php#L247-248

The config array above has no value for proxy in it.

No error occurs on the selenium node.

When I use firefox using the following config no error occurs:

default:
     paths:
         features: 'features'
         bootstrap: 'features/bootstrap'
     context:
         parameters:
             javascript_session: selenium
             browser: chrome
             show_cmd: open %s
     extensions:
         Behat\MinkExtension\Extension:
             base_url: 'http://example.co.uk/'
             default_session: selenium2
             browser_name: firefox
             selenium2:
               capabilities:
                 browserName: firefox
                 browser: firefox
                 browserVersion: 15
                 version: "15"

Notes

As this is a chrome only problem I'm assuming that the issue is with the ChromeDriver. A similar issue was encountered in the selenium remote driver bindings for perl.

teodesian/Selenium-Remote-Driver#36

Environment

Selenium Hub: OSX 10.7
Command used to start hub:

selenium-server-standalone-2.25.0.jar -role hub

Selenium Node: Windows 7 Ultimate (vm)
Command used to start node:

java -jar selenium-server-standalone-2.25.0.jar
 -Dwebdriver.chrome.driver="C:\Users\Administrator\Downloads\chromedriver_win_23
.0.1240.0\chromedriver.exe" -role node -hub http://192.168.56.1:4444/grid/regist
er -host 192.168.56.101 -browser browserName=firefox,version=15,maxInstances=1 -
browser browserName=chrome,version=21,maxInstances=1 

url should match with placeholder

Hello,
Today I've notice unexpected behaviour statement when using value from TableNode:
@Then /^the (?i)url(?-i) should match (?P<pattern>"([^"]|\\")*")$/
It generates broken formatted output:
Then the url should match "<placeholder{-skipped}{+skipped_param}>{-skipped_param}{+skipped}"
instead of expected:
Then the url should match "<placeholder>"

After small research, solution is pretty easy, update regex to exclude nested block of pattern inside quotes as its done on all other text/match patterns:
@Then /^the (?i)url(?-i) should match (?P<pattern>"(?:[^"]|\\")*")$/

Regards,
Nick

"base_url" conflict between symfony driver and zombie driver

I'm creating scenarios which some use the default symfony driver and some others that need javascript use the zombie driver.
I have had to create the app_test.php file and write the full path to it in the "base_url" option of the extension to make the zombie test work.
But then the scenarios that use the symfony driver use the "base_url" too to build the routes and of course, these don't exist. I'm I missconfigurating something?

Disable SSL checks in Goutte

I keep getting SSL errors when attempting to test my login functionality.

When I follow "Login"                                # FeatureContext::clickLink()
      [curl] 60: SSL certificate problem, verify that the CA cert is OK. Details:
      error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed [url]

I've tried adding the curl parameters to the sessions/goutte.xml file, but I'm not sure I'm doing it correctly.

I've added the following, but I'm still getting errors. Can someone tell me to proper way to accomplish this? I've looked through the Guzzle Docs and found this page explaining how to pass parameters to guzzle, but the XML doesn't seem to be working as expected.

        <parameter key="behat.mink.goutte.guzzle_parameters" type="collection">
            <parameter key="curl.options" type="collection">
                <parameter key="CURLOPT_SSL_VERIFYPEER">false</parameter>
                <parameter key="CURLOPT_CERTINFO">false</parameter>
            </parameter>
            <parameter key="ssl.certificate_authority">false</parameter>
        </parameter>

[2.0] Removing the MinkDictionary

The MinkDictionary is a trait which can be used only in one of your contexts. I suggest removing it:

  • Behat 3.0 supports a clean way to register both your context and the MinkContext in a suite
  • a trait which can be used only once seems really weird as traits are meant to enable horizontal reuse
  • the logic checking whether the class uses the trait (to avoid having to add implements MinkAwareContext on the context class) is clearly a hack
  • making the Mink steps translatable still requires some work in the context class when using the trait to import the Mink translations

for all these reasons, I would find it cleaner to only ship RawMinkContext and MinkContext, and to leave MinkDictionary out. What do you think @everzet ?

not able to select option having text which appears in many options in list.

Hi ,
I am unable to select "Manager" option from a select list which has another option "Accounts Manager" as well."Accounts Manager is selected" when I use below mentioned step in MinkContext.

@when /^(?:|I )select "(?P(?:[^"]|"))" from "(?P(?:[^"]|"))"$/ I think statement in step definition is not working as expected. $this->getSession()->getPage()->selectFieldOption($select, $option);

The capabilites "Selenium-version" and "Max-duration" does not work

Capabilities with a "-" in the name is changed to an underscore which makes them not recognizable.

Eg. max-duration specified in behat.yml with "-" gives the following error:

[Symfony\Component\Config\Definition\Exception\InvalidConfigurationException]

Unrecognized options "max_duration" under "behat.extensions.behat_minkextension_extension.selenium2.capabilities.firefox"

Set Mink Parameters

Hi,

I saw in RawMinkContext that there is a method to set the Mink Parameters (setMinkParameter). That's fine, but as we don't have an access to all the MinkParameters (instead of one at a time via getMinkParameter), it is pretty useless, except if we want to erase all the parameters...

So there are two options. Either we need to add either a setMinkParameter method, or either a getMinkParameters method.

I need this in order to be able to use a "wildcard url", as sometimes i need to be on a specific subdomain on my application, and sometimes not. Like http://%slocalhost, where I replace the %s via a (s)printf with a proper value.

I would gladly do a PR, but I don't know which option you prefer...

Exception thrown by (//html/.//*[self::input ..

I've these two steps:

    Then the response should contain "LoginForm_username"
    And I fill in "LoginForm_username" with "ugolupo"

The first one works. The second, ... no.
I get this exception:

And I fill in "LoginForm_username" with "ugolupo" # FeatureContext::fillField()
Exception thrown by (//html/.//[self::input | self::textarea | self::select][not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')][(((./@id = 'LoginForm_username' or ./@name = 'LoginForm_username') or ./@id = //label[contains(normalize-space(string(.)), 'LoginForm_username')]/@for) or ./@Placeholder = 'LoginForm_username')] | .//label[contains(normalize-space(string(.)), 'LoginForm_username')]//.//[self::input | self::textarea | self::select][not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')])[1]
Form submit button for field with xpath "(//html/.//[self::input | self::textarea | self::select][not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')][(((./@id = 'LoginForm_username' or ./@name = 'LoginForm_username') or ./@id = //label[contains(normalize-space(string(.)), 'LoginForm_username')]/@for) or ./@Placeholder = 'LoginForm_username')] | .//label[contains(normalize-space(string(.)), 'LoginForm_username')]//.//[self::input | self::textarea | self::select][not(./@type = 'submit' or ./@type = 'image' or ./@type = 'hidden')])[1]"not found.

My composer is:

"require": {
    "behat/behat": "2.4.*@stable",
    "behat/mink": "1.4.*@stable",
    "behat/mink-extension": "*",
    "behat/mink-goutte-driver": "*",
    "behat/mink-selenium2-driver": "*"
},
"minimum-stability": "dev",
"config": {
    "bin-dir": "bin/"
}

Improved form handling

This is more of a feature request.

I have ran into a situation where getting to write the test fixture is harder than it should. I am working to write functional tests on a legacy application using Selenium WebDriver and Behat.

I often run into situations where the tests would look like this:

Given I am authenticated as "..."
When I fill "abc" with "123"
And I press "Go"
Then ...

The issue is that the page contains the Go label on multiple buttons and there is no other constant field I can rely on for the button. IDs are being auto-generated and the other values are not constant. Modifying the application to change these is not an option. We're trying to get there, but Behat is part of the transition process.

There is a simple heuristic for this. Before searching for the whole page for the button, begin by searching in the form the last input was filled in.

I implemented this locally in my FeatureContext, but I feel it would be useful for more people. The implementation I have is not so clean as I ran into several issues while implementing it.

Among others:

  • Identity is not preserved when using getParent()
  • Lookup has to be re-implemented in fillField() and pressButton() as it is entirely delegated to Mink, which does not provide the field back.

Session is reset between BeforeScenario and actual Scenario

Hi,

I need to populate some $_SESSION (or cookies, whatever) before every scenario is run.
I thought that using BeforeScenario hook would be a great idea.

However, the problem is that as soon as BeforeScenario finishes, the session is reset.

Shouldn't the session be reused throuoghout the "whole scenario runtime"? That is BeforeScenario then actual Scenario then AfterScenario.

Do you have any recommendations if this is not feasible?

Cheers.

MinkContext not loaded by default

Hello,

the documentations says at http://docs.behat.org/cookbook/behat_and_mink.html that "It should show you all the predefined web steps as MinkExtension will automatically use bundled MinkContext if no user-defined context class found."

If you do :

cd /tmp
mkdir behat-mink-test
cd behat-mink-test
echo '{
    "require": {
        "behat/behat": "2.4.*@stable",
        "behat/mink": "1.4.*@stable",
        "behat/mink-extension": "*",
        "behat/mink-goutte-driver": "*",
        "behat/mink-selenium2-driver": "*"
    },
    "minimum-stability": "dev",
    "config": {
        "bin-dir": "bin/"
    }
}
' > composer.json
curl http://getcomposer.org/installer | php
php composer.phar install
echo "# behat.yml
default:
    extensions:
        Behat\MinkExtension\Extension:
            goutte: ~
            selenium2: ~
" > behat.yml
bin/behat --init
bin/behat -dl

You will see that MinkContext is not loaded by default

Unable to specify Selenium version in SauceLabsFactory

Hi Guys,

I'm facing difficulties while trying to specify the selenium version in the Saucelabs factory driver

My behat structure looks like this:

sauce:
  extensions:
    Behat\MinkExtension\Extension:
      default_session: saucelabs
      saucelabs:
        username: <myuname>
        access_key: <myapikey>
        capabilities:
          platform: "Windows 2012 R2"
          version: "34"
          name: "[Regression] Windows 2012 R2 chrome"
          selenium-version: "2.38.0"

But then I got the following error;
Unrecognized options "selenium_version" under "behat.extensions.behat_minkextension_extension.saucelabs.capabilities"

Kind regards!

Feature: Add support for iOS-driver capabilities

Mink yells at me when I try to use some of the capabilities for iOS-driver in my behat.yml.

I looked around for documentation on writing my own definitions for things like this, but couldn't find any. Attempts to patch my own copy seem to be wrought with failure.

iphone:
  context:
    class: IPhoneRunner
  extensions:
    Behat\MinkExtension\Extension:
      browser_name: iphone
      selenium2:
        wd_host: "http://127.0.0.1:5555/wd/hub"
        capabilities:
          browser: iphone
          browserName: iPhone
          deviceType: iphone
          platform: mac
          version: "7.1"

Capabilities are listed here: https://github.com/ios-driver/ios-driver/blob/dev/common/src/main/java/org/uiautomation/ios/IOSCapabilities.java#L43-L84

Behat 2.5.x compatibility?

There doesn't seem to be any behat/mink-extension version that is install-able through composer when using "behat/behat": "2.5.0".
Latest MinkExtension composer.json
"behat/behat": "~2.4.5",

According to the Behat changelog not much seem to have changed between 2.4.6 and 2.5.0 ( Behat/Behat@b7e0e98 ) so I'm guessing the MinkExtension should be made compatible with the new Behat LTS release?

Default browser window size in configuration

It would be great to have a default browser window size that can be defined in configuration, otherwise I have to add an extra step in every Behat scenario of the kind:
'And I set browser window size to "1024" x "768"'

missing name attribute breaks form fillField

I was experiencing something similar to #89 when I found the answer.

I'm reporting this because it seems like something that should be handled, or at least warned in the error message with the enormous exception from #89

I was using a mockup of the page to start testing the testing, and the forms did not have all the fields necessary to be functional. In particular the name html attribute didn't exist on the fields I was testing.

I was using MinkContext and goutte (symfony2 session version) with:

When I fill in "username" with "test"

So I changed this:

<input id="username" value="{{ last_username }}" />

to this:

<input id="username" name="_username" value="{{ last_username }}" />

As soon as I realized that, I was able to fix this problem entirely. I also switched to working forms with associated actions and methods, but in my brief testing, that was the culprit. If a form field doesn't have a name attribute filled out, it isn't selectable via the goutte drive.

@sensorario it was that simple

The capability for firefox profile does not work

According to 'Extension.php' the profile should be specified as:

Behat\MinkExtension\Extension:    
      selenium2:
        capabilities: {'firefox': {'profile':'/path-to-zip'} }

The profile though doesn't get applied - instead webdriver creates an anonymous profile.

guzzle_options does not seem to work anymore for disabling curl SSL checks

I used to use the following behat.yml to disable SSL checks for goutte:

        Behat\MinkExtension\Extension:
            goutte:
                guzzle_parameters:
                    curl.CURLOPT_SSL_VERIFYPEER: false
                    curl.CURLOPT_CERTINFO: false

However, since updating it seems that goutte is ignoring these settings and throwing the same SSL errors again. Is there a new syntax that needs to be used to work with the most recent version of goutte/mink?

Selectively disable session reset for tests

The idea is to be able to annotate a test to indicate the session should not be reset.

For example, in the absence of a loop construct in Gherkin, Scenario Outlines may be used to iterate through a table of choices, that doesn't require test isolation.

So, for performance, we could annotate it (eg., "exposed") and still have the readability of a table.

fillFields doesn't work when using Selenium2

Hey, I tried using Selenium2 driver and fillFields and ended up failing, due to "array to string conversion" . As a side note, everything worked fine with Goutte.
I've solved the issue for myself with the following patch to MinkContext.php:

Index: vendor/behat/mink-extension/src/Behat/MinkExtension/Context/MinkContext.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- vendor/behat/mink-extension/src/Behat/MinkExtension/Context/MinkContext.php (revision )
+++ vendor/behat/mink-extension/src/Behat/MinkExtension/Context/MinkContext.php (revision )

@@ -117,8 +118,13 @@
      */
     public function fillFields(TableNode $fields)
     {
-        foreach ($fields->getRowsHash() as $field => $value) {
-            $this->fillField($field, $value);
+        foreach ($fields->getHash() as $field) {
+            if(isset($field['id']) && strlen($field['id']))
+              $this->fillField($field['id'], $field['value']);
+            else if(isset($field['name']) && strlen($field['name']))
+              $this->fillField($field['name'], $field['value']);
+            else if(isset($field['label']) && strlen($field['label']))
+              $this->fillField($field['label'], $field['value']);
         }
     }

Any comments are welcome. Also, let me know if anyone else experiences a similar problem. If you find this patch applicable, feel free to use it.

No matching package found \w Behat 3.0.6

Hi guys,

I can't seem to get over this error when installing the mink-extension.

» php composer.phar update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - behat/mink-extension v1.3.3 requires behat/behat ~2.5.0 -> no matching package found.
    - behat/mink-extension v1.3.2 requires behat/behat ~2.5.0 -> no matching package found.
    - behat/mink-extension v1.3.1 requires behat/behat ~2.5.0 -> no matching package found.
    - behat/mink-extension v1.3.0 requires behat/behat ~2.5.0 -> no matching package found.
    - behat/mink-extension v1.2.0 requires behat/behat ~2.5.0 -> no matching package found.
    - behat/mink-extension v1.1.4 requires behat/behat ~2.4.5 -> no matching package found.
    - behat/mink-extension v1.1.3 requires behat/behat ~2.4.5 -> no matching package found.
    - behat/mink-extension v1.1.2 requires behat/behat ~2.4.5 -> no matching package found.
    - behat/mink-extension v1.1.1 requires behat/behat ~2.4.5 -> no matching package found.
    - behat/mink-extension v1.1.0 requires behat/behat ~2.4.5 -> no matching package found.
    - behat/mink-extension v1.0.1 requires behat/behat >=2.4,<2.5-dev -> no matching package found.
    - behat/mink-extension v1.0.0 requires behat/behat >=2.4.0,<2.5.0-dev -> no matching package found.
    - Installation request for behat/mink-extension * -> satisfiable by behat/mink-extension[v1.0.0, v1.0.1, v1.1.0, v1.1.1, v1.1.2, v1.1.3, v1.1.4, v1.2.0, v1.3.0, v1.3.1, v1.3.2, v1.3.3].

Potential causes:
 - A typo in the package name
 - The package is not available in a stable-enough version according to your minimum-stability setting
   see <https://groups.google.com/d/topic/composer-dev/_g3ASeIFlrc/discussion> for more details.

Read <http://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.

Tried the .phar install as specified here, but i don't know how to inherit the MinkContext class.

Fatal error: Class 'Behat\MinkExtension\Context\MinkContext' not found in /Users/...

Any help would be appreciated.

Error with MinkDictionary and non-English language

When using MinkDictionary, non-English languages are not enable.
For example:

class FeatureContext extends BehatContext 
{
      use MinkDictionary;
}

$ bin/behat -di --lang fr

only shows the English pre defined steps.

Solution : make my ContextClass implements the TranslatedContextInterface :

class FeatureContext extends BehatContext implements TranslatedContextInterface
{
    use MinkDictionary;
}

Problem :
$ bin/behat -di --lang fr

PHP FATAL error : Class FeatureContext contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Behat\Behat\Context\TranslatedContextInterface::getTranslationResources)

The solution seems easy : The MinkDictionary.php lacks this simple method :

/**
 * Returns list of definition translation resources paths.
 *
 * @return array
 */
public function getTranslationResources()
{
    return $this->getMinkTranslationResources();
}

This is the same as in MinkContext.php

As far as I know, no error after this modification.

Parsing dynamic values in Behat/Mink Yml file configurations through Mink Extension.php(Selenium2) for Saucelabs

I was wondering if there's a possible way to parse dynamic values, specifically the name by using the *.feature Behat/Mink tests as it's running the into the Yml configuration file with Selenium2 Capabilities

The behat.yml file uses Behat/Mink/Extension extension file with Selenium 2 Capabilities parameters in the file.

        default:
          context:
            class:  'FeatureContext'
          extensions:
            Behat\MinkExtension\Extension:
             base_url: 
             javascript_session:  'selenium2'
             goutte:
             selenium2:
                browser: firefox
                wd_host: <sauce username>:<accesscode>@ondemand.saucelabs.com/wd/hub
                capabilities: {  "platform": "Windows 7" , "version": "21" , "name":"Test" }

Within the Extension.php file:
https://github.com/Behat/MinkExtension/blob/2.0/src/Behat/MinkExtension/Extension.php

                arrayNode('selenium2')->
                    children()->
                        scalarNode('browser')->
                            defaultValue(isset($config['selenium2']['browser']) ? $config['selenium2']['browser'] : '%behat.mink.browser_name%')->
                        end()->
                        arrayNode('capabilities')->
                            normalizeKeys(false)->
                            children()->
                                scalarNode('browserName')->
                                    defaultValue(isset($config['selenium2']['capabilities']['browserName']) ? $config['selenium2']['capabilities']['browserName'] : 'firefox')->
                                end()->
                                scalarNode('version')->
                                    defaultValue(isset($config['selenium2']['capabilities']['version']) ? $config['selenium2']['capabilities']['version'] : "9")->
                                end()->
                                scalarNode('platform')->
                                    defaultValue(isset($config['selenium2']['capabilities']['platform']) ? $config['selenium2']['capabilities']['platform'] : 'ANY')->
                                end()->
                                scalarNode('browserVersion')->
                                    defaultValue(isset($config['selenium2']['capabilities']['browserVersion']) ? $config['selenium2']['capabilities']['browserVersion'] : "9")->
                                end()->
                                scalarNode('browser')->
                                    defaultValue(isset($config['selenium2']['capabilities']['browser']) ? $config['selenium2']['capabilities']['browser'] : 'firefox')->
                                end()->
                                scalarNode('ignoreZoomSetting')->
                                    defaultValue(isset($config['selenium2']['capabilities']['ignoreZoomSetting']) ? $config['selenium2']['capabilities']['ignoreZoomSetting'] : 'false')->
                                end()->
                                scalarNode('name')->
                                    defaultValue(isset($config['selenium2']['capabilities']['name']) ? $config['selenium2']['capabilities']['name'] : 'Behat Test')->
                                end()->
                                scalarNode('deviceOrientation')->
                                    defaultValue(isset($config['selenium2']['capabilities']['deviceOrientation']) ? $config['selenium2']['capabilities']['deviceOrientation'] : 'portrait')->
                                end()->
                                scalarNode('deviceType')->
                                    defaultValue(isset($config['selenium2']['capabilities']['deviceType']) ? $config['selenium2']['capabilities']['deviceType'] : 'tablet')->
                                end()->
                                scalarNode('selenium-version')->
                                    defaultValue(isset($config['selenium2']['capabilities']['selenium-version']) ? $config['selenium2']['capabilities']['selenium-version'] : '2.31.0')->
                                end()->
                                scalarNode('max-duration')->
                                    defaultValue(isset($config['selenium2']['capabilities']['max-duration']) ? $config['selenium2']['capabilities']['max-duration'] : '300')->
                                end()->
                                booleanNode('javascriptEnabled')->end()->
                                booleanNode('databaseEnabled')->end()->
                                booleanNode('locationContextEnabled')->end()->
                                booleanNode('applicationCacheEnabled')->end()->
                                booleanNode('browserConnectionEnabled')->end()->
                                booleanNode('webStorageEnabled')->end()->
                                booleanNode('rotatable')->end()->
                                booleanNode('acceptSslCerts')->end()->
                                booleanNode('nativeEvents')->end()->
                                booleanNode('passed')->end()->
                                booleanNode('record-video')->end()->
                                booleanNode('record-screenshots')->end()->
                                booleanNode('capture-html')->end()->
                                booleanNode('disable-popup-handler')->end()->
                                arrayNode('proxy')->
                                    children()->
                                        scalarNode('proxyType')->end()->
                                        scalarNode('proxyAuthconfigUrl')->end()->
                                        scalarNode('ftpProxy')->end()->
                                        scalarNode('httpProxy')->end()->
                                        scalarNode('sslProxy')->end()->
                                    end()->
                                    validate()->
                                        ifTrue(function ($v) {
                                            return empty($v);
                                        })->
                                        thenUnset()->
                                    end()->
                                end()->
                                arrayNode('firefox')->
                                    children()->
                                        scalarNode('profile')->
                                            validate()->
                                            ifTrue(function ($v) {
                                                return !file_exists($v);
                                            })->
                                                thenInvalid('Cannot find profile zip file %s')->
                                            end()->
                                        end()->
                                        scalarNode('binary')->end()->
                                    end()->
                                end()->
                                arrayNode('chrome')->
                                    children()->
                                        arrayNode('switches')->
                                            prototype('scalar')->end()->
                                        end()->
                                        scalarNode('binary')->end()->
                                        arrayNode('extensions')->
                                            prototype('scalar')->end()->
                                        end()->
                                    end()->
                                end()->
                            end()->
                        end()->
                        scalarNode('wd_host')->
                            defaultValue(isset($config['selenium2']['wd_host']) ? $config['selenium2']['wd_host'] : 'http://localhost:4444/wd/hub')->
                        end()->
                    end()->
                end()->
                arrayNode('saucelabs')->
                    children()->
                        scalarNode('username')->
                            defaultValue(getenv('SAUCE_USERNAME'))->
                        end()->
                        scalarNode('access_key')->
                            defaultValue(getenv('SAUCE_ACCESS_KEY'))->
                        end()->
                        booleanNode('connect')->
                            defaultValue(isset($config['saucelabs']['connect']) ? 'true' === $config['saucelabs']['connect'] : false)->
                        end()->
                        scalarNode('browser')->
                            defaultValue(isset($config['saucelabs']['browser']) ? $config['saucelabs']['browser'] : 'firefox')->
                        end()->
                        arrayNode('capabilities')->
                            children()->
                                scalarNode('name')->
                                    defaultValue(isset($config['saucelabs']['name']) ? $config['saucelabs']['name'] : 'Behat feature suite')->
                                end()->
                                scalarNode('platform')->
                                    defaultValue(isset($config['saucelabs']['platform']) ? $config['saucelabs']['platform'] : 'Linux')->
                                end()->
                                scalarNode('version')->
                                    defaultValue(isset($config['saucelabs']['version']) ? $config['saucelabs']['version'] : '21')->
                                end()->
                                scalarNode('deviceType')->
                                    defaultValue(isset($config['saucelabs']['deviceType']) ? $config['saucelabs']['deviceType'] : null)->
                                end()->
                                scalarNode('deviceOrientation')->
                                    defaultValue(isset($config['saucelabs']['deviceOrientation']) ? $config['saucelabs']['deviceOrientation'] : null)->

Under Extension.php in the MinkExtension directory, it loads up the selenium2.xml file with a set of arrays to parse the information in that file onto the behat.yml.

I noticed that if there isn't any parameters from the Selenium2 capabilities specified in the yml file, the Extension.php will assign a default value based on the array name:

scalarNode('name')-> defaultValue(isset($config['selenium2']['capabilities']['name']) ? $config['selenium2']['capabilities']['name'] : 'Behat Test')->

With this said, I was wondering if there's any possible way to use the name of the Behat/Mink Feature tests <test>.feature within my local directory to parse a title within the name while the tests are running.

Injecting services which rely on Mink Session into a context

I was trying to implement injecting of page objects as a constructor into context files. With the way MinkExtension registers a default session, I'm getting an InvalidArgumentException with "Specify session name to get".

What would prevent the issue, but not realy fix it, is setting a default session name on SuiteTested::BEFORE (example below is based on the SessionListener):

 $session = $this->getDefaultSession($event->getSuite());
 $this->mink->setDefaultSessionName($session);

This wouldn't fix the issue since the session might be changed per scenario and page object might get a reference to a wrong session.

Is this something we can fix either here or in Behat?

Selenium2Driver maximize window capability

I was wondering whether there was a possibility to get selenium to maximize browser windows using the capabilities configuration parameter in behat.yml?

I've been looking at the Extension.php file which doesn't define any such capability, while selenium does. See http://selenium.googlecode.com/svn/trunk/docs/api/py/webdriver_remote/selenium.webdriver.remote.webdriver.html#selenium.webdriver.remote.webdriver.WebDriver.maximize_window

Or is there any other way to get selenium to maximize my browser windows should they (for whatever reason) choose not to start fully maximized?

@javascript Scenario Outline broken again

Hi,

it seems that a similar issue like this one (#9) popped up again.

I'm using default Mink driver to run my tests and want to have Selenium2 to run JavaScript tests. Therefore I'm using "@javascript" in certain feature files. Behat recognizes this annotation and function prepareDefaultMinkSession() in mink-extension/src/Behat/MinkExtension/Listener/SessionsListener.php sets the default session name to "selenium2" according to my config because I set javascript_session to selenium2. Problem is: Behat uses the existing Mink session and does not change the mink session to the desired Selenium2-Driver / Session. This results in goutte running my test though it was marked "@javascript".

Regards,
Jens

Mink doesn't find link title when using qTip JQuery Plugin

Hi,

I am having issue while writing one scenerio, the system uses qTip JQuery Plugin which renames title to oldtitle(to avoid browser tooltip) and I can't use text value because the text must be the same for whole table entries. So the scenario fails because can't find the link.

I was thinking about to work on a pull request which adds contains(./@oldtitle, %locator%) to link selector in NamedSelector class. Or Is there any better solution?

Get response reason phrase

Reason phrase is a great fonctionnal alternative to status code. But I don’t find how get them.

Could you implement Behat\Mink\Session::getStatusReasonPhrase (or whatever) and a corresponding step, like:

the response status should be "(?P<reason>[^"]*)

BehatContext and PageObjectContext wont open browser

Basically I want something like a super context (called LoginContext) that will call multiple subcontexts.

It will login the user and check if the user is on the customer account.

So I call the CustomerLogin context that will login the user, and later I call CustomerAccount that checks the user is on the customer account page.

<?php

use Behat\Behat\Context\BehatContext;

class LoginContext extends BehatContext
{   
    public function __construct()
    {
        $this->useContext("customer_login", new CustomerLoginContext());
        $this->useContext("customer_account", new CustomerAccountContext());    
    }

    /**
     * @Given /^I am logged$/
     */
     public function iAmLogged()
    {
        $this->getSubContext("customer_login")->iAmOnCustomerLogin();
        $this->getSubContext("customer_login")->iLogin();

        $this->getSubContext("customer_account")->iShouldSeeMyOrders();
    }
}

And my subcontexts are PageObjectContext classes, like this:

<?php

use pages\CustomerLogin;
use SensioLabs\Behat\PageObjectExtension\Context\PageObjectContext;

class CustomerLoginContext extends PageObjectContext
{
    ...
}

and this subcontext class call a Page class:

<?php

namespace pages;

use SensioLabs\Behat\PageObjectExtension\PageObject\Page;
use Commons\Utils;

class CustomerLogin extends Page
{   
    ...
}

Despite the tests pass, I don't see the browser opening. My behat.yml file is fine:

login:
  paths:
    bootstrap: app/context
  context:
    class:  'LoginContext'
  extensions:
    SensioLabs\Behat\PageObjectExtension\Extension:
      namespaces:
        page: pages
    Behat\MinkExtension\Extension:
      base_url:  '<base-url-hidden-because-i-cant-show>'
      javascript_session:  'selenium'
      browser_name: googlechrome
      goutte:              ~
      selenium:

The tests run on command line, and the test pass, but the browser wont open. I guess it's because it's not using Mink's session to access the browser's driver.

Selenium is running, but Mink doesn't even call anything there, there is no log being shown on selenium terminal.

So my questions is, how do I use Mink's drivers with PageObjects. I've read somewhere that I should use BehatBundle class, but it's obsolete so I tried using Symphony2Extension. I have tried extending RawMinkContext and using MinkDictionary trait, but nothing. Am I following the right path? If not, which way should I follow?

Thanks in advance.

[2.0] Improving the configuration of sessions

Currently, the MinkExtension does not allow configuring sessions. It allow configuring a driver and registers a session using it (the best way to figure it is to see the name of the sessions).
Because of this, users wanting to write scenarios involving multiple sessions of the same type tried to clone the Mink Session object to get a second one. But this does properly, as it involves cloning the driver as well (and all potential dependencies of the driver), while maintaining a coherent object graph (we don't want to clone the same instance twice in the new object graph, as it would not look the same way anymore). Thus, cloning drivers often does not work as the dependencies of the driver are often not designed to be cloned (this is the case for BrowserKitDriver where a PR cloning the CookieJar has been explicitly rejected as BrowserKit could not consider either that all its implementations can be cloned).

A better implementation would allow configuring as many sessions as you want (at least 1), and choosing the driver type for each of them. This way, it would become trivial to have several sessions for a scenario (just define them).
I know how I would like to see the configuration:

mink:
    # a few global settings go there
    default_session: ~ # the default session is set to the first defined one by default
    # ...
    sessions:
        first:
            goutte:
                # ...
        second:
            selenium: # ...

In each session, exactly 1 child can be set (corresponding to the driver you want to use). The advantage is that we can keep a clear list of the allowed settings for each driver.

This is exactly the same principle than the configuration of the user provider in the Symfony SecurityBundle

This approach however requires changing the way other extensions can provide additional drivers. Currently, they simply register a session for their driver in the container and tag it to let MinkExtension know about it.
For the new approach, the other extensions should not extend the container, but the MinkExtension itself, by registering a DriverFactory, which can provide the config tree for the driver, and the build the driver service definition when it is selected for a session. Being able to do this requires adding an additional extension point in Testwork, between the registration of extensions and the processing of the configuration (and probably a new method in the Extension interface), so it should be done before we release Behat 3.0 (we could delay it for 3.1 by adding the new method in a separate optional interface instead, to preserve BC on Extension).

The equivalent of this extra extension point in Symfony is done by putting the logic in the Bundle::build method.

If you agree that this refactoring is a good idea, I will work on the Behat Testwork changes required to allow it.

ignoreZoomSetting - IEDriverServer.exe - Selenium2

Hello,
I had problem with the IEDriverServer.exe with selenium2:

WARN - Exception: Unexpected error launching Internet Explorer. Browser zoom level was set to >104%. It should be set to 100% (WARNING: The server did not provide any stacktrace information).

I found out the webdriver might need the "ignoreZoomSetting" capability setting, but the mink extension does not allow it.
I added this line to Extension.php Line 246:

<?php
booleanNode('ignoreZoomSetting')->end()->

now your capabilites line can look like this in the behat.yml

capabilities: {browser:"iexplore", "platform": "WINDOWS", "version": "9","ignoreZoomSetting":true}

Official documentation is out of date

It still recommends using Behat\MinkExtension\Extension, but this will cause an error:

[Behat\Testwork\ServiceContainer\Exception\ExtensionInitializationException]
`Behat\MinkExtension\Extension` extension file or class could not be located.

Using Behat\MinkExtension as per #142 also does not work:

[Symfony\Component\Config\Definition\Exception\InvalidConfigurationException]
Unrecognized options "context" under "testwork" 

How does one use Mink with Behat 3.0?!

cc @rjmackay

assertPageMatchesText breaks when including double-quote in regex

I'm trying to match the following regex but

Then I should see text matching "{\"code\":\".*\",\"state\":\"testing\"}"

when I try to run the scenario I'm getting
Warning: preg_match(): Unknown modifier 'c' in /Users/robbie/devel/Lamu/vendor/behat/mink/src/Behat/Mink/WebAssert.php on line 210

and from the trace it looks like the regex gets passed to preg_match with the escaping removed from the double quotes
'"{"code":".*","state":"testing"}"',

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.