Why am I unable to catch the Unexpected Alert Exception? - php

I am using a try catch block to catch an exception and I am unable to catch it as it still says:
In Exception.php line 155:
unexpected alert open: {Alert text : The form is not complete and has not been submitted yet. There is 1 problem with your submission.}
(Session info: chrome=73.0.3683.75)
(Driver info: chromedriver=2.41.578700 (2f1ed5f9343c13f73144538f15c00b370eda6706),platform=Linux 4.15.0-38-generic x86_64)
My feature file:
<?php
use Behat\Behat\Hook\Scope\AfterStepScope;
use Behat\Behat\Tester\Exception\PendingException;
use Behat\Behat\Context\Context;
use Behat\MinkExtension\Context\MinkContext;
use WebDriver\Exception\UnexpectedAlertOpen;
/**
* Defines application features from the specific context.
*/
class FeatureContext extends MinkContext implements Context
{
/**
* Initializes context.
*
* Every scenario gets its own context instance.
* You can also pass arbitrary arguments to the
* context constructor through behat.yml.
*/
public function __construct()
{
}
/**
* #Given I fill in the email field with :email
*/
public function iFillInTheEmailFieldWith($email)
{
dump($email);
$this->visit('/471w2222');
$page = $this->getSession()->getPage();
$page->find('xpath', '//*[#id="tfa_1111"]')->setValue($email);
}
/**
* #When I submit the form
*/
public function iSubmitTheForm()
{
try {
$page = $this->getSession()->getPage();
$page->find('xpath', '//*[#id="submit_button"]')->click();
}
catch (UnexpectedAlertOpen $e){
dd($e->getMessage());
$this->getSession()->getDriver()->getWebDriverSession()->accept_alert();
}
}
}
The alert shows up :
$page->find('xpath', '//*[#id="submit_button"]')->click();
executes. But it is unable to catch it. Why?

As per the error message...
(Session info: chrome=73.0.3683.75)
(Driver info: chromedriver=2.41.578700 (2f1ed5f9343c13f73144538f15c00b370eda6706),platform=Linux 4.15.0-38-generic x86_64)
...the main issue is the incompatibility between the version of the binaries you are using as follows:
You are using chromedriver=2.41
Release Notes of chromedriver=2.41 clearly mentions the following :
Supports Chrome v67-69
You are using chrome=73.0
Release Notes of ChromeDriver v2.46 clearly mentions the following :
Supports Chrome v71-73
So there is a clear mismatch between the ChromeDriver v2.41 and the Chrome Browser v73.0
Solution
Upgrade ChromeDriver to current ChromeDriver v2.46 level.
Keep Chrome version between Chrome v73 levels. (as per ChromeDriver v2.45 release notes)
Clean your Project Workspace through your IDE and Rebuild your project with required dependencies only.
If your base Web Client version is too old, then uninstall it and install a recent GA and released version of Web Client.
Take a System Reboot.
Execute your #Test.
Always invoke driver.quit() within tearDown(){} method to close & destroy the WebDriver and Web Client instances gracefully.

Related

How to set the locale on a Symfony CLI command?

I run a multi-language Symfony 4.4 website where the locale is part of the URL. So I have /it/, /fr/ and so on.
My routes look like this:
/**
* #Route({
* "it": "/it/azienda/",
* "es": "/es/empresa/"
* }, name="app_cms_about")
*/
Then I've a pre-controller event that set the correct locale:
public function onRouteRequest(ControllerEvent $event)
{
// ... checks and stuff ...
$event->getRequest()->setLocale($ln);
}
Everything works as expected via web, but now I need to manage this language difference in a CLI Command: basically it means that when I run $this->urlGenerator->generate('app_cms_about') from the CLI, I expect to get the locale-based URL.
The user must pass the locale to the CLI Command to as an argument:
protected function configure()
{
$this->addArgument(
"app_language",
InputArgument::REQUIRED,
'The site to run on: `it`, `es`, ...');
}
Now I just need to set this somehow. I'd love to it with an event, but of course there is no getRequest() on the CLI event to set the locale on.
How do I set the locale on a Symfony 4 CLI Command?
Setting the locale does not make a lot of sense for a console application. What has a locale is the user request, and there is no request during a command line run.
But you want seems to be to be able to get URLs with the appropriate locale:
Then, straight from the docs:
When a route is localized, Symfony uses by default the current request locale. Pass a different '_locale' value if you want to set the locale explicitly
E.g.:
$aboutUrlIt = $this->router->generate('app_cms_about', ['_locale' => 'it']);
You mention in comments the setting default_locale, and that since you can change this it means console applications "have a locale set". But you are reaching the wrong conclussion from this: this setting is to set a default locale in case where no locale is set in the request. Or, for example, when there is no request, as in a command line application.
You cannot change that setting during runtime, because that setting is part of the compiled container, which is compiled before the application is run.
Following Symfony calls with xdebug I was able to find the solution I was looking for. I built a listener as the one I'm using via web:
services:
App\EventListener\CommandStartListener:
tags:
- { name: kernel.event_listener, method: onCommandStart, event: console.command }
<?php
namespace App\EventListener;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Routing\RouterInterface;
class CommandStartListener
{
protected RouterInterface $router;
public function __construct(RouterInterface $router)
{
$this->router = $router;
}
public function onCommandStart(ConsoleCommandEvent $event) : ?string
{
// ... checks and stuff ...
try {
$lnParam = $event->getInput()->getArgument("app_language");
} catch( \Exception $ex) {
return null;
}
$this->router->getContext()->setParameter('_locale', $lnParam);
return $lnParam;
}
}
This makes any urlGenerator->generate() behave correctly.
hat tip to #yivi for pointing me into the right direction.

Laravel Dusk Can't Read Click of Undefined

I tried simple demo of laravel dusk but I get the following error; I tried to update composer installer as suggested by some solution and also tried to set duskcommand.php as suggested on git but still having the error.
Warning: TTY mode is not supported on Windows platform.
PHPUnit 7.3.5 by Sebastian Bergmann and contributors.
[1004/130622.087:ERROR:gpu_process_transport_factory.cc(1007)] Lost UI shared context.
Tests\Browser\RegisterTest::testExample
Facebook\WebDriver\Exception\UnknownServerException: unknown error: Cannot read property 'click' of undefined
(Session info: headless chrome=69.0.3497.100)
(Driver info: chromedriver=2.35.528161 (5b82f2d2aae0ca24b877009200ced9065a772e73),platform=Windows NT 10.0.17134 x86_64)
I'm trying this demo in Windows 10.
below is my RegisterTest.php
<?php
namespace Tests\Browser;
use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class RegisterTest extends DuskTestCase
{
/**
* A Dusk test example.
*
* #return void
*/
public function testExample()
{
$this->browse(function ($browser) {
$browser->visit('/') //Go to the homepage
->clickLink('Register') //Click the Register link
->assertSee('Register') //Make sure the phrase in the argument is on the page
//Fill the form with these values
->value('#name', 'Joe')
->value('#email', 'joe#example.com')
->value('#password', '123456')
->value('#password-confirm', '123456')
->click('button[type="submit"]') //Click the submit button on the page
->assertPathIs('/home') //Make sure you are in the home page
//Make sure you see the phrase in the argument
->assertSee("You are logged in!");
});
}
}

DoctrineCacheBundle: Flush cache via SYmfony route

Over my Symfony project I use the DoctrineCacheBundle and I want when I visit http://example.com/api/cache/flush I want to uncache (flush) any cached key.
The sole reason is because I have applications that visit the url above in order to remove any cached result.
As far I searched the DoctrineCacheBundle uses a command in order to uncache the cached results (as you can see via php ./bin/console list doctrine:cache command):
Symfony 3.3.12 (kernel: app, env: dev, debug: true)
Usage:
command [options] [arguments]
Options:
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
-e, --env=ENV The environment name [default: "dev"]
--no-debug Switches off debug mode
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands for the "doctrine:cache" namespace:
doctrine:cache:clear Flush a given cache
doctrine:cache:contains Check if a cache entry exists
doctrine:cache:delete Delete a cache entry
doctrine:cache:flush [doctrine:cache:clear] Flush a given cache
doctrine:cache:stats Get stats on a given cache provider
But how can I do this programmatically?
The best way is to make your own Cache adapter by following one of theese 2 approaches:
Approach 1: Use dedicated manager for uncaching:
namespace AppBundle\CacheManagers;
use Doctrine\Common\Cache\FlushableCache;
class PurgeAllcachesManager
{
/**
* #var FlushableCache
*/
private $purgeCachingHandler=null;
public function __construct(FlushableCache $purgeCachingHandler)
{
$this->purgeCachingHandler=$purgeCachingHandler;
}
/**
* Method that does all the dirty job to uncache all the keys
*/
public function uncache()
{
$this->purgeCachingHandler->flushAll();
}
}
Approach2: Do as Doctrine does:
namespace AppBundle\CacheManagers;
use Doctrine\Common\Cache\Cache as CacheHandler;
class PurgeAllcachesManager
{
/**
* #var CacheHandler
*/
private $cacheHandler=null;
public function __construct(CacheHandler $cacheHandler)
{
$this->cacheHandler=$cacheHandler;
}
/**
* Method that does all the dirty job to uncache all the keys
* #throws Exception
*/
public function uncacheAllKeys()
{
if(!method_exists($this->purgeCachingHandler) ){
throw new Exception("You cannot empty the cache");
}
$this->purgeCachingHandler->flushAll();
}
//Yet another methods to handle the cache
}
Also have a look on this question for extra info on how to use it.

WURFL memory allocation fatal error

I was using WURFL just fine, then all of a sudden it's throwing this error:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 65484 bytes) in /var/wwwlibs/vnd/WURFL/lib/CustomDevice.php on line 118
I've found some stuff online about Tera-WURFL, but (afaik) I'm not using that, but just the downloaded version from sourceforge. Someone suggested updating the SimpleXML, but I'm just confused as to why WURFL's going over the top.
My wrapper class is as follows:
<?php
namespace vnd\WURFL;
use \WURFL_Configuration_InMemoryConfig;
use \WURFL_WURFLManagerFactory;
/**
* File: WURFL_bootstrap.php
* Sets up and readies the WURFL library for platform and browser detection.
*/
require_once 'WURFL/lib/Application.php';
// ----- WURFL constants ------ //
define('WURFL_ROOT', dirname(__FILE__).'/');
# Directories
define('WURFL_RESOURCES_DIR', WURFL_ROOT.'resources/');
define('WURFL_PERSISTENCE_DIR', WURFL_RESOURCES_DIR.'storage/persistence');
define('WURFL_CACHE_DIR', WURFL_RESOURCES_DIR.'storage/cache');
class WURFLBootstrap extends WURFL_Configuration_InMemoryConfig {
const WURFL_WATCH_MODE = "performance";
const WURFL_VERSION = '2.3.3';
const WURFL_CACHE_EXP = 36000;
# Our WURFL Manager
private $_manager;
# Our device where the capabilities lie
private $_device;
public function __construct(){
$zipPath = $this->getPath();
if(!is_file($zipPath))
die($zipPath.' is not a valid file.');
if(!is_dir(WURFL_PERSISTENCE_DIR) || !is_dir(WURFL_CACHE_DIR))
die(WURFL_PERSISTENCE_DIR.' or '.WURFL_CACHE_DIR.' are not valid directories.');
$this->wurflFile($zipPath);
$this->matchMode(self::WURFL_WATCH_MODE);
$this->persistence('file', array('dir' => WURFL_PERSISTENCE_DIR));
$this->cache('file', array('dir' => WURFL_CACHE_DIR, 'expiration' => self::WURFL_CACHE_EXP));
// Automatically reload the WURFL data if it changes
$this->allowReload(true);
// Create a WURFL Manager Factory from the WURFL Configuration
$wurflManagerFactory = new WURFL_WURFLManagerFactory($this);
// Create our factory and start the process.
$this->_device = $wurflManagerFactory->create()->getDeviceForHttpRequest($_SERVER);
}
/**
* Returns the path to our ZIP file
*/
private function getPath(){
return WURFL_RESOURCES_DIR.'/wurfl-'.self::WURFL_VERSION.'.zip';
}
/**
* Seeing as this is a wrapper class, any calls to our $wflManager (or whatever
* we happened to be assigned to) should be passed on to the actual
* manager object where all the goodies lie.
*
*/
public function __call($name, $arguments){
//return $this->device->$name($arguments);
}
public function getDevice(){
return $this->_device;
}
}
The computer this is running on is an old laptop, so it's not stocked on memory, but what gives? I removed everything that could be causing an over-allocation of memory, but so far it seems like WURFL just doesn't want to run.
I also tried clearing my cache and persistence directories and running it again, but no dice.
One thing I'm thinking is to use the XML configuration class as opposed to the WURFL_Configuration_InMemoryConfig (based on the name I assume it's storing everything in memory, at least temporarily, hence the crash), but I'm curious why it's all of a sudden throwing this error.
I'm not familiar with that library, but in general, you can find out exactly where things go wrong by registering a shutdown function and printing the last error there.
Add the following piece of code somewhere at the start of your script (i.e. before the error occurs):
function my_shutdown_function() {
echo "SHUTDOWN!\n";
$err = error_get_last();
if($err) {
print_r($err);
// optionally, if you want a stack trace:
$ex = new Exception;
print_r($ex->getTraceAsString());
}
}
register_shutdown_function('my_shutdown_function');
You can have similar fun with set_error_handler and set_exception_handler if you like, although both of these will never catch a fatal error (among other failures).

Trouble executing the Yii web service demo

I'm fairly new to Yii and am currently trying to use this framework to create some PHP web services. While trying to execute the brief tutorial on web services provided on the Yii web site http://www.yiiframework.com/doc/guide/1.1/en/topics.webservice#declaring-web-service-action I ran into some trouble. Namely, I get a "Maximum execution time of 60 seconds exceeded" fatal error when executing the script. My guess is that the getPrice() method actually never gets called.
I'd appreciate any suggestions related to why this may be happening. The contents of my index.php file are listed below. (Note that the Yii gramework is properly installed and I'm running PHP 5.3.0 with the php_soap extension).
<?php
$yii=dirname(__FILE__).'/../yii/framework/yii.php';
defined('YII_DEBUG') or define('YII_DEBUG',true);
defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3);
require_once($yii);
class StockController extends CController{
function __construct(){
parent::__construct($this->id, $this->module);
}
public function actions(){
return array(
'quote'=>array(
'class'=>'CWebServiceAction',
),
);
}
/**
* #param string the symbol of the stock
* #return float the stock price
* #soap
*/
public function getPrice($symbol){
$prices=array('IBM'=>100, 'GOOGLE'=>350);
return isset($prices[$symbol])?$prices[$symbol]:0;
//...return stock price for $symbol
}
}
$client=new SoapClient('http://localhost/SampleWebService/?r=stock/quote');
echo $client->getPrice('GOOGLE');
?>
It seems strange that you are declaring the call in the index.php entry script... I'm also not sure why you are overriding the constructor?
And I think, if this really in your entry script, you are missing call the create the application, either Yii::createWebApplication($config)->run(); or Yii::createConsoleApplication($config)->run();, depending on if you are running this as a web or console application.
Have you made sure that the application is running as expected without the SOAP/services stuff? I would set up a basic Hello World app (web or console), then try the web services.

Categories