Behat with Mink - php

Does anyone know how to successfully configure Mink to work with Behat? In case if anyone doesn't know, Behat is a BDD(Behaviour-Driven Development) framework for PHP and Mink provides a browser emulators abstraction layer to test with.
You can find out more about Behat at http://behat.org/ and Mink at https://github.com/Behat/Mink or http://www.knplabs.com/fr/blog/one-mink-to-rule-them-all
Basically i followed the instructions at http://www.knplabs.com/fr/blog/one-mink-to-rule-them-all to configure my Mink to work with my Behat. My behat.yml, the one located inside the Behat folder, not the Mink folder, is as follows:
default:
paths:
features: %%BEHAT_CONFIG_PATH%%/features
formatter:
name: progress
pretty:
formatter:
name: pretty
parameters:
multiline_arguments: false
default:
environment:
parameters:
start_url: http://localhost/
imports:
- mink/behat.yml
I also have the following code in my features/support/boostrap.php
require_once 'mink/autoload.php';
However, having the following code in my features/support/env.php
$world->client = new \Goutte\Client;
would give me a PHP Fatal error: Class 'Goutte\Client' not found in terminal(OSX) when i use the behat command. This happens even if i have the goutte.phar inside my behat/Mink/Vendor/Goutte folder.
Hope anyone can enlighten me on where i went wrong and if there was any part in the question where I wasn't being clear about it, do let me know. Thanks a lot.

Here it is: https://github.com/knplabs/mink-demo ;-)
Basically, with Mink, you don't need to create or require Goutte client it's done by Mink automatically. Your $world was also enhanced and now you're able to get mink session inside step definitions:
$downloadsLink = $world->getSession()->getPage()->findLink('downloads');
Also, you've forgot to include PHPUnit!
See mink-demo for getting great example ;-)

Related

Problem with layer when using serverless-offline with Bref

I'm trying to run a Symfony application with Bref and serverless-offline. I know that Bref doesn't officially support serverless-offline, but I want to give it a shot; this thread - https://github.com/brefphp/bref/issues/875 - implies that it should be possible but I'm not getting the error described there yet.
When I run sls invoke local -f MyLambda I get this error:
{"errorType":"exitError","errorMessage":"RequestId: 09256631-dcc7-1775-350e-b0c10a2c9c00 Error: Couldn't find valid bootstrap(s): [/var/task/bootstrap /opt/bootstrap]"}
So I assume that serverless-offline fails to get the layer correctly. The directory .serverless/layers contains a sub-structure php-81-fpm/18 for the PHP layer but it is empty.
What's important is that I'm running this setup in a development Docker container. I mounted the docker socket so the Docker daemon on the host is used.
The serverless.yml looks like this (simplified):
plugins:
- ./vendor/bref/bref
- serverless-offline
functions:
MyLambda:
handler: public/index.php
layers:
- ${bref:layer.php-81-fpm} # also tried with 'arn:aws:lambda:eu-central-1:209497400698:layer:php-81-fpm:18'
custom:
serverless-offline:
host: 0.0.0.0
useDocker: true
dockerHost: host.docker.internal
I'm happy to provide further information, please let me know. Don't hesitate to suggest "low-level" things as I'm quite new to this ecosystem. Thanks for your help!

How to mock, use or override Environment::isCli() in TYPO3 v9 unit tests

I'm trying to get a TYPO3 v8 system updated to TYPO3 v9, but when it comes to unit-testing, I got some errors. I was able to fix some of them on my own but this one here's a very difficult one for me, because unit-testing is somewhat new to me in general.
I already searched the web, the TYPO3 documentation (which seems like the important parts are missing?), asked some friends and tried some things on my own, but nothing helped.
$this->environmentMock = $this->createMock(Environment::class);
$this->environmentMock->expects($this->once())
->method("::isCli")
->will($this->returnValue(TRUE));
I'm expecting to manually override the static function ::isCli() that comes with the Environment class. If that's not possible, is there any other "workaround", like setting a protected variable or something like that?
Currently this is my error message:
Trying to configure method "::isCli" which cannot be configured because it does not exist, has not been specified, is final, or is static
Thanks in advance!
Update 1:
After using #susis tip, I get the following error when appending the code:
TypeError: Return value of TYPO3\CMS\Core\Core\Environment::getContext() must be an instance of TYPO3\CMS\Core\Core\ApplicationContext, null returned
Additional information: My project is just an extension folder with TYPO3 v9 sources required in its own composer.json. No web, no htdocs, just the extension folder.
Update 2:
Here's a full gist of my test file.
Update 3:
Even the debugger isn't helping me in this case, see attached screenshot:
xdebug phpstorm applicationcontext environment screenshot
Update 4:
I updated the gist, added the environment vars to the phpunit.xml file and added parent::setUp() to the top of the setUp() method but the error is still the same:
TypeError : Return value of TYPO3\CMS\Core\Core\Environment::getContext() must be an instance of TYPO3\CMS\Core\Core\ApplicationContext, null returned
/Users/xyz/my_redirect/public/typo3/sysext/core/Classes/Core/Environment.php:97
/Users/xyz/my_redirect/Tests/Unit/Hooks/RequestHandlerHookTest.php:41
Update 5:
I updated the gist and removed the environment settings from the phpunit.xml due to what I've seen that they didn't work either. At this moment, the test is working but I'm still not sure if it's done the right way. Thanks for your help!
You can initialize the Environment you want in your tests, for example with:
Environment::initialize(
Environment::getContext(),
true,
false,
Environment::getProjectPath(),
Environment::getPublicPath(),
Environment::getVarPath(),
Environment::getConfigPath(),
Environment::getBackendPath() . '/index.php',
Environment::isWindows() ? 'WINDOWS' : 'UNIX'
);
This is the same way as it is done in TYPO3 Core tests and allows you to customize the complete environment. If you are using the TYPO3 testing framework / UnitTestCase base classes, you can use the property protected $backupEnvironment = true; to make sure the environment is reset after your test.
For an example, you can have a look at the ResourceCompressorIntegrationTest

Yii2 Codeception invalid routing?

I am trying to set-up acceptance tests using Codeception in Yii2.
So far so good with regards to installation, but I am having a route issue.
When I do:
codeception run acceptance
I get this feedback:
1) Failed to ensure login page works in LoginCept (./acceptance/LoginCept.php)
Step I fill field "input[name="LoginForm[username]"]",""
Fail Form field by Label or CSS element with 'input[name="LoginForm[username]"]' was not found.
Scenario Steps:
3. $I->fillField("input[name="LoginForm[username]"]","")
2. // I am going to submit login form with no data
1. $I->amOnPage("/backend/web/index-test.php/")
The input with name LoginForm[username] exists on the page, but apparantly Codeception is not getting the correct page.
Should /backend/web/index-test.php also have the approot path in it? When I request approot/backend/web/index-test.php in the browser it all works fine.
Thanks for any pointers.
Alex
UPDATE: hereby the contents of acceptance.suite.yml:
# Codeception Test Suite Configuration
# suite for acceptance tests.
# perform tests in browser using the Selenium-like tools.
# powered by Mink (http://mink.behat.org).
# (tip: that's what your customer will see).
# (tip: test your ajax and javascript by one of Mink drivers).
# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES.
class_name: AcceptanceTester
modules:
enabled:
- PhpBrowser
- tests\codeception\common\_support\FixtureHelper
# you can use WebDriver instead of PhpBrowser to test javascript and ajax.
# This will require you to install selenium. See http://codeception.com/docs/04-AcceptanceTests#Selenium
# "restart" option is used by the WebDriver to start each time per test-file new session and cookies,
# it is useful if you want to login in your app in each test.
# - WebDriver
config:
PhpBrowser:
# PLEASE ADJUST IT TO THE ACTUAL ENTRY POINT WITHOUT PATH INFO
url: http://localhost:8080
# WebDriver:
# url: http://localhost:8080
# browser: firefox
# restart: true
UPDATE BASED ON COMMENTS BELOW:
I'm lost. I tried hardcoding the path, and even tried hardcoding the localhost URL, but then I get this response:
$I->amOnPage("/backend/web/index-test.php/localhost/www/yii2KickDish/backend/web")
which clearly is a bogus URL....so how can I get Codeception to resolve to the right location?
I got the same issue.
Seems like the "amOnPage" method build into the AcceptanceTesterActions trait isnt working well with yii2 url pattern.
That's how i solved this.
Create a class MainTester extending from AcceptanceTester
namespace tests\codeception\master\Step\Acceptance;
use tests\codeception\master\AcceptanceTester;
class MainTester extends AcceptanceTester
{
public function amOnPage($url)
{
$page = \Yii::$app->getUrlManager()->createUrl($url);
return parent::amOnPage($page);
}
}
Then in my Cest class
use tests\codeception\master\Step\Acceptance\MainTester as AcceptanceTester;
class TestClassCest
{
public function testMethod(AcceptanceTester $I)
{
$I->amOnPage('/example/something');
}
}

Clearing cache for laravel 4 app before codeception tests

I'm using codeception to run acceptance tests for a laravel app. One problem I've been into is is that my login tests start failing when the login page gets cached and, I guess, I'm getting logged in automatically. I think this is the case because my tests start passing again when I clear the cache and they'll generally start failing without my having changed the tests or the application code at all.
Here's the login test in question, now extracted into a helper method
public function login($username, $password, $I) {
$I->amOnPage('users/login');
$I->fillField('email', $username);
$I->fillField('password', $password);
$I->click('Login');
$I->amOnPage('admin/');
$I->see('Welcome');
}
I've been clearing the cache periodically whenever the tests fail but it's becoming tedious. I'd like to be able to register a helper to clear the cache for me and just call the function in all my tests. I extracted the function into a helper as suggested here with the following function in AcceptanceHelper.php:
public function clearCache($I) {
$cache = $this->getModule('Cache');
$cache->flush();
}
This seems to be what was suggested by the documentation here, but I get the error "Module Cache couldn't be connected". It looked like I needed the Laravel4 module so I added that to my acceptance.suite.yml file but no luck there either I received this error:
SQLSTATE[28000] [1045] Access denied for user 'stephen'#'localhost' (using password: NO)
I thought I'd need to authorize mysql in the config file, but that didn't seem to work either. Here's my acceptance.suite.yml file:
class_name: AcceptanceTester
modules:
enabled:
- PhpBrowser
- AcceptanceHelper
- Laravel4
config:
PhpBrowser:
url: 'http://104.131.29.69:8000/'
Laravel4:
user: 'root'
password: 'pAsSwOrD'
Finally I read this answer and it seemed as though I shouldn't actually have included Laravel4 in the config file and that my helper function should look more like this:
public function clearCache($I) {
$L = $I->getLaravel4();
Cache::flush();
}
But I just wind up getting this error instead:
Class 'Codeception\Module\Cache' not found
So I'm stuck. Thanks!
Artisan::call('cache:clear');
is better approach.
Ok so I figured out how to do this. Apparently there's a module called cli which you can include in the acceptance.suite.yml file like this:
class_name: AcceptanceTester
modules:
enabled:
- PhpBrowser
- AcceptanceHelper
- Cli
This module allows you to use shell commands in your script with the runShellCommand() function. Since my cache is stored in files in the app/storage/cache/ directory the shell command I need to execute is:
rm app/storage/cache/*
and voilá cache cleared. Then in the test file it will look like this:
$I->runShellCommand('rm -rf app/storage/cache/*');
I decided to simplify this a bit by including it in the function I used to login, since I knew I'd want to clear the cache before each login I just included that line in a login function inside AcceptanceHelper, which then is accessible in all of my tests.
This is a bit of workaround since it isn't agnostic to the kind of caching I'm using (if I were to use memcached I would need to do something different) but it worked for me so I thought I'd share it.

Handling Laravel's UserTrait with ApiGen

I've started using ApiGen with a Laravel project.
When I run it, I get the following error:
The class Illuminate\Auth\UserTrait is in use but has not been found in the defined sources.
Clearly it's complaining because Laravel's UserTrait isn't defined in the same file, but I obviously don't want to include my vendor/ directory and from the documentation I don't see how I can handle this. I want to use Jenkins to generate the documentation and because it returns a non-zero exit code it registers as an error, and thus breaks the build.
Here's my apigen.neon:
source:
- app
destination: docs
exclude:
- "*/tests/*.php"
- "*/database/*"
tree: true
sourceCode: true
todo: true
autocomplete:
# default
- classes
- constants
- functions
# other
- methods
- properties
- classconstants
title: My web app
Any idea how I can accomplish this?
EDIT 2019: I'm current owner of ApiGen.
ApiGen development stopped 3 years ago and it lacks of support and meaning. I do not recommend to use it
This should be fixed in last version (RC5 at the moment).
See: https://github.com/apigen/apigen/releases
For any further issues you can use Github issues to report them

Categories