Have you watched this episode? https://laracasts.com/series/cypress-and-laravel-integration/episodes/1
How to update environment/config variable in Cypress?
Is there anyway to set config variables either before or during Cypress tests? It may not be possible but this is what I have tried...
I have a some routes like:
Route::get('/_testing/config', 'Cypress\CypressConfigController@getConfig');
Route::post('/_testing/config', 'Cypress\CypressConfigController@setConfig');
Then in controller:
public function getConfig()
{
return config()->get(request('key'));
}
public function setConfig()
{
config()->set(request('key'), request('value'));
return config()->get(request('key'));
}
Then from a Cypress test I want to update some config like:
cy.request({
method: 'POST',
url: '/_testing/config?key=somekey&value=somevalue',
form: true,
}).its('body').then((res) => {
console.log(res);
// 'somevalue'
});
When running this the correct config item is returned and I assume should be then reflected in the app (I have some environment vars to toggle sections of a site) but... it doesn't work...
Is this simply not possible. to do in this manner? I do not really want to have multiple .env files and switch them depending on test types, although this could be possible as a last resort.
Thanks.
The config set is indeed set but only lasts for the request it is set inside. It is shortlived but needs to persist across all request within a test scenario.
So this is how I have solved this in the end. I am sure this will be useful to someone else in the future so making sure I document this here:
Firstly I have made a test route:
// Environment override route
Route::post('/_testing/environment', 'Cypress\CypressEnvironmentController@override');
The route is called from a simple cypress command:
Cypress.Commands.add('env', (params = {}) => {
cy.request({
method: 'POST',
url: '/_testing/environment',
form: true,
body: {
overrides: params,
}
})
});
Then in the test it can be used before the test runs like this:
// Change any config you like
cy.env({ 'queue.default' : 'sync'});
// Then continue the test
The controller override method looks like this:
// This method will take any params passed in the request and write them to an .overrides file.
public function override(): void
{
if(! request()->has('overrides')){
throw new \Exception('No override variables specified!');
}
file_put_contents(storage_path('.overrides'), '');
foreach(request()->overrides as $key => $value) {
file_put_contents(storage_path('.overrides'), $key.'='.$value.''.PHP_EOL, FILE_APPEND);
}
}
Then finally I have added a middleware which checks the contents of this file and sets the config on the fly but only during Cypress testing:
public function handle($request, Closure $next)
{
if(! app()->environment('cypress')) {
return $next($request);
}
// Get overrides contents as an array
$overrides = file(storage_path('.overrides'), FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
// Set config
foreach ($overrides as $line => $value) {
$config = explode('=', $value);
config()->set($config[0], $config[1]);
}
return $next($request);
}
Top prevent any pollution between tests. Ensure that the .overrides file is emptied before each test in the global beforeEach:
beforeEach(() => {
cy.exec("> storage/.overrides");
});
And thats it! It works perfectly. Just ensure the .overrides file is added to .gitignore so it doesn't get into version control.
Please or to participate in this conversation.