I'm trying to use Behat and Mink to test a symfony 2.1 project.
My FeatureContext.php:
<?php
use Behat\Behat\Context\ClosuredContextInterface,
Behat\Behat\Context\BehatContext,
Behat\Behat\Exception\PendingException,
Behat\Behat\Context\Step;
use Behat\Gherkin\Node\PyStringNode,
Behat\Gherkin\Node\TableNode;
use Behat\MinkExtension\Context\MinkContext;
//
// Require 3rd-party libraries here:
//
// require_once 'PHPUnit/Autoload.php';
// require_once 'PHPUnit/Framework/Assert/Functions.php';
//
/**
* Features context.
*/
class FeatureContext extends Behat\MinkExtension\Context\MinkContext {
/**
* Initializes context.
* Every scenario gets it's own context object.
*
* #param array $parameters context parameters (set them up through behat.yml)
*/
public function __construct(array $parameters)
{
// Initialize your context here
}
//
// Place your definition and hook methods here:
//
// /**
// * #Given /^I have done something with "([^"]*)"$/
// */
// public function iHaveDoneSomethingWith($argument)
// {
// doSomethingWith($argument);
// }
//
}
composer.json
"behat/behat": ">=2.2.2",
"behat/mink": ">=1.3.2",
"behat/symfony2-extension": "*",
"behat/mink-extension": "*",
"behat/mink-browserkit-driver": "*",
"behat/mink-selenium-driver": "*"
app/config/behat.yml
default:
extensions:
Behat\Symfony2Extension\Extension:
mink_driver: true
kernel:
env: test
debug: true
Behat\MinkExtension\Extension:
base_url: 'http://localhost:8080/app_test.php/'
default_session: symfony2
javascript_session: selenium
selenium:
host: 127.0.0.1
port: 4444
When I do ./bin/behat I get:
Feature: Login
In order to login
As a user
I need to be able to validate the username and password
Scenario: Link to login page # features/login.feature:7
PHP Fatal error: Call to a member function getSession() on a non-object in vendor/behat/mink-extension/src/Behat/MinkExtension/Context/RawMinkContext.php on line 81
Fatal error: Call to a member function getSession() on a non-object in vendor/behat/mink-extension/src/Behat/MinkExtension/Context/RawMinkContext.php on line 81
Any idea?
v.
Your behat.yml should not be located in app/config/behat.yml , but in your/project/root/behat.yml
Thanks for #Stuart and #spiritoo answers here.
Firstly, move the behat.yml from /config to project root.
Secondly, content for the behat.yml:
default:
suites:
my_suite:
contexts:
- FeatureContext
extensions:
Behat\Symfony2Extension: ~
Behat\MinkExtension:
base_url: http://en.wikipedia.org
goutte: ~
sessions:
default:
symfony2: ~
Finally, in project root, run:
vendor/bin/behat features/{YOUR TEST FILE HERE}
My composer.json file:
"require-dev": {
"behat/behat": "^3.3",
"behat/mink": "^1.7",
"behat/mink-extension": "^2.2",
"behat/mink-browserkit-driver": "^1.3",
"behat/mink-goutte-driver": "^1.2",
"behat/symfony2-extension": "^2.1",
"behat/mink-selenium2-driver": "^1.3"
}
Related
So a little context: I have an old project in symfony 2.8 and php 5.6
Composer have been abandonned by the previous developper and i'm trying to make it work again. I had a bunch of conflicting versions, url to previous svn, i've updated some package ect.
Now everything is installing fine but the clear cache from the post-update-cmd crash with this error :
PHP Fatal error: Class 'P2\Bundle\RatchetBundle\P2RatchetBundle' not found in /Project/app/AppKernel.php on line 19
I'm loading 2 vendor from private gitlab, both are installed but no matter which one i try to call in registerBundles()
I can't find the real cause of this error.
So here the code :
composer.json :
...
"repositories" : [
{
"type": "package",
"package": {
"name": "p2/ratchet-bundle",
"version": "dev-master",
"type": "package",
"source": {
"url": "https://git-dev.my-company.fr/my-company-bundles/ratchet-bundle.git",
"type": "git",
"reference": "master"
}
}
}
...
"require" : {
"p2/ratchet-bundle" : "dev-master",
...
}
AppKernel.php
class AppKernel extends Kernel {
public function registerBundles() {
$bundles = array(
...
new P2\Bundle\RatchetBundle\P2RatchetBundle(),
...
);
return $bundles;
}
public function registerContainerConfiguration(LoaderInterface $loader) {
$loader->load(__DIR__ . '/config/config_' . $this->getEnvironment() . '.yml');
}
}
There is no problem to get the bundle from the gitlab repo. It appears into the installed.json and installed.php of composer vendor
This bundle is installed in Project/vendor/p2/ratchet-bundle/P2RatchetBundle.php
namespace P2\Bundle\RatchetBundle;
/**
* Class P2RatchetBundle
* #package P2\Bundle\RatchetBundle
*/
class P2RatchetBundle extends Bundle
{
At the moment, i can't use the console or load any page with this new setup. It's probably just a small thing i missed but i can't figure what.
If you want some more information just ask
I have a cli project that I am using Symfony's Dependency Injection and Console components. I am not using a Kernel, controllers, etc.
When using autoconfigure: true, the service doesn't get the console.command tag it is supposed to.
My composer.json:
{
"require": {
"php": "^7.4",
"monolog/monolog": "^2.0",
"symfony/console": "^5.0",
"symfony/dependency-injection": "^5.0",
"symfony/config": "^5.0",
"symfony/yaml": "^5.0"
},
"autoload": {
"psr-4": {"Mudder\\": "src/"}
}
}
./config/services.yaml:
services:
_defaults:
autowire: true
autoconfigure: true
Mudder\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
public: true
./src/Mudder/Command/HelloWorld.php:
<?php
namespace Mudder\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class HelloWorld extends Command
{
protected static string $defaultName = 'test';
protected function configure()
{
$this->setDescription('Foo');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln('Hello, world.');
return 0;
}
}
Finally, ./test.php (the cli entrypoint):
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
$containerBuilder = new ContainerBuilder();
$loader = new YamlFileLoader($containerBuilder, new FileLocator(__DIR__ . '/config'));
$loader->load('services.yaml');
$containerBuilder->compile();
print_r($containerBuilder->getDefinition(\Mudder\Command\HelloWorld::class)->getTags());
Output from the print_r() is an empty array "Array()"
The container itself does know nothing about a Command.
If you want to auto configure your commands, you have to call
$containerBuiler->registerForAutoconfiguration(Command::class)->addTag('console.command');
or load the FrameworkExtension (from symfony FrameworkBundle)
Your command should end with Command. Rename it to HelloWorldCommand.
can you help me please?
I have a problem for simple scenario gerkins that don't find fields with error
Form field with id|name|label|value|placeholder "searchform-search" not found. (Behat\Mink\Exception\ElementNotFoundException)
but selecium launches chrome correctly.
I use mink/behat symfony, selecium, chrome-driver.
For example my scenario i use https://hotexamples.com/.
behat.yml
default:
autoload:
- "%paths.base%/tests/api/bootstrap"
extensions:
Behat\Symfony2Extension:
kernel:
bootstrap: tests/api/bootstrap/bootstrap.php
class: App\Kernel
Behat\MinkExtension:
base_url: https://hotexamples.com
goutte: ~
selenium2: ~
browser_name: chrome
suites:
default:
contexts:
- Context\FeatureContext:
kernel: '#kernel'
paths: [ "%paths.base%/tests/api", "%paths.base%/tests/behat"]
FeatureContext:
<?php
declare(strict_types=1);
namespace Context;
use Behat\Behat\Context\Context;
use Behat\Behat\Context\SnippetAcceptingContext;
use Behat\MinkExtension\Context\MinkContext;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\KernelInterface;
/**
* This context class contains the definitions of the steps used by the demo
* feature file. Learn how to get started with Behat and BDD on Behat's website.
*
* #see http://behat.org/en/latest/quick_start.html
*/
class FeatureContext extends MinkContext implements Context, SnippetAcceptingContext
{
/**
* #var KernelInterface
*/
private $kernel;
/**
* #var Response|null
*/
private $response;
public function __construct(KernelInterface $kernel)
{
$this->kernel = $kernel;
}
/**
* #Given I wait for the page to be loaded
*/
public function iWaitForThePageToBeLoaded()
{
$this->getSession()->wait(5000, "document.readyState === 'complete'");
}
/**
* #Given I wait :time seconds
*/
public function iWaitSeconds(int $time)
{
sleep($time);
}
}
Scenario:
Feature: TestBehat
#javascript #api
Scenario: Search
Given I am on the homepage
When I fill in "searchform-search" with "behat"
composer.json
"require-dev": {
"behat/behat": "^3.5",
"behat/mink": "~1.7#dev",
"behat/mink-browserkit-driver": "^1.3",
"behat/mink-extension": "^2.3",
"behat/mink-goutte-driver": "^1.2",
"behat/mink-selenium2-driver": "^1.3",
"behat/symfony2-extension": "^2.1",
"behatch/contexts": "^3.2",
"doctrine/instantiator": "^1.3",
"hautelook/alice-bundle": "^2.5",
"nikic/php-parser": "^4.3",
"phpstan/phpstan": "^0.12.3",
"phpunit/phpunit": "^8.5",
"symfony/maker-bundle": "^1.11",
"symfony/var-dumper": "4.2.*"
}
And output of console
vendor/bin/behat
Feature: TestBehat
#javascript #api
Scenario: Search # tests/behat/authentication.feature:4
12:09:24.452 INFO [ActiveSessionFactory.apply] - Capabilities are: {
"browser": "firefox",
"browserName": "chrome",
"ignoreZoomSetting": false,
"name": "Behat feature suite",
"tags": [
"debian",
"PHP 7.3.12-1+0~20191128.49+debian9~1.gbp24559b"
]
}
12:09:24.453 INFO [ActiveSessionFactory.lambda$apply$11] - Matched factory org.openqa.selenium.grid.session.remote.ServicedSession$Factory (provider: org.openqa.selenium.chrome.ChromeDriverService)
Starting ChromeDriver 79.0.3945.36 (3582db32b33893869b8c1339e8f4d9ed1816f143-refs/branch-heads/3945#{#614}) on port 31246
Only local connections are allowed.
Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code.
12:09:24.796 INFO [ProtocolHandshake.createSession] - Detected dialect: W3C
12:09:24.797 INFO [RemoteSession$Factory.lambda$performHandshake$0] - Started new session db80a68bb2beb001693480d14ffa7b1f (org.openqa.selenium.chrome.ChromeDriverService)
Given I am on the homepage # Context\FeatureContext::iAmOnHomepage()
When I fill in "searchform-search" with "behat" # Context\FeatureContext::fillField()
Form field with id|name|label|value|placeholder "searchform-search" not found. (Behat\Mink\Exception\ElementNotFoundException)
--- Scénarios échoués:
tests/behat/authentication.feature:4
1 scénario (1 échecs)
2 étapes (1 succès, 1 échecs)
0m2.11s (19.49Mb)
12:09:26.573 INFO [ActiveSessions$1.onStop] - Removing session db80a68bb2beb001693480d14ffa7b1f (org.openqa.selenium.chrome.ChromeDriverService)
Thanks
Problem solved by changing the configuration file for chrome options with mink
default:
autoload:
- "%paths.base%/tests/api/bootstrap"
calls:
error_reporting: 16383 # E_ALL & ~E_USER_DREPRECATED
extensions:
Behat\Symfony2Extension:
kernel:
bootstrap: tests/api/bootstrap/bootstrap.php
class: App\Kernel
Behat\MinkExtension:
browser_name: chrome
base_url: 'http://127.0.0.1:8080/'
goutte: ~
selenium2: ~
sessions:
default:
selenium2:
capabilities:
extra_capabilities:
chromeOptions:
args:
- "--disable-gpu"
- "--window-size=1920,1080"
w3c: false
suites:
default:
contexts:
- Context\FeatureContext:
kernel: '#kernel'
paths: [ "%paths.base%/tests/api", "%paths.base%/tests/behat"]
I use Symfony 2.8 and Behat 3.3. I have standard FeatureContext class in project_root/features/bootstrap directory. Before scenario execution I want purge DB like that:
/**
* #BeforeScenario
*/
public function beforeScenario()
{
// use Doctrine\Common\DataFixtures\Purger\ORMPurger
$purger = new ORMPurger($this->em);
$purger->purge();
}
But when I execute test I receive error:
The annotation "#Doctrine\ORM\Mapping\Entity" in class XXX does not
exist, or could not be auto-loaded.
My behat.yml is:
default:
suites:
default:
contexts:
- FeatureContext:
em: '#doctrine.orm.entity_manager'
extensions:
Behat\Symfony2Extension:
kernel:
bootstrap: "vendor/autoload.php"
env: "test"
debug: "true"
composer.json autoload section:
"autoload": {
"psr-4": {
"": "src/"
},
"classmap": [
"app/AppKernel.php",
"app/AppCache.php"
]
}
If remove line bootstrap: "vendor/autoload.php" from behat.yml, everything will work as needed.
i'm am trying tu use Behat + Mink + Selenium2Driver into Symfony2.
i ran Selenium Server.
my behat.yml is:
default:
extensions:
Behat\Symfony2Extension\Extension:
mink_driver: true
Behat\MinkExtension\Extension:
default_session: 'symfony2'
base_url: http://localhost/fhm_mind_solution/app_dev.php/
selenium2:
wd_host: 'http://127.0.0.1:4444/wd/hub'
capabilities: { "browser": "firefox", "version": "23"}
in my FeatureContext.php:
class FeatureContext extends RawMinkContext
implements KernelAwareInterface
{
private $kernel;
private $parameters;
public function __construct(array $parameters)
{
$this->useContext('mink', new MinkContext);
}
/* [...] */
public function iCanAuthenticateAsAnAdmin()
{
$this->getSession();
}
when i lauch Behat, i have always this: "could not open connection". What is missing?
Firstly, you didn't configure selenium driver properly. It should be:
default:
extensions:
Behat\Symfony2Extension\Extension:
mink_driver: true
Behat\MinkExtension\Extension:
default_session: 'symfony2'
base_url: http://localhost/fhm_mind_solution/app_dev.php/
selenium2:
wd_host: 'http://127.0.0.1:4444/wd/hub'
capabilities: { "browser": "firefox", "version": "23"}
Secondly, you don't have to initialize the driver nor the session yourself. It's done for you by the MinkExtension.
Simply make that your context extends the Behat\MinkExtension\Context\RawMinkContext and you'll get access to the $this->getSession() method.
Read more in the official docs: http://extensions.behat.org/mink/
You can see available capabilities in the selenium2 configuration: https://github.com/Behat/MinkExtension/blob/2.0/src/Behat/MinkExtension/services/sessions/selenium2.xml#L10