Completed
Push — develop ( 321e68...dce9ea )
by Carsten
09:20
created

CoreContext::getEventManager()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 * YAWIK
4
 *
5
 * @filesource
6
 * @license MIT
7
 * @copyright  2013 - 2017 Cross Solution <http://cross-solution.de>
8
 */
9
10
namespace Yawik\Behat;
11
12
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
13
use Behat\MinkExtension\Context\MinkContext;
14
use Behat\MinkExtension\Context\RawMinkContext;
15
use Core\Repository\RepositoryService;
16
use Jobs\Repository\Categories;
17
use Zend\Mvc\Application;
18
19
20
/**
21
 * Class FeatureContext
22
 * @package Yawik\Behat
23
 */
24
class CoreContext extends RawMinkContext
25
{
26
	static protected $application;
27
	
28
	/**
29
	 * @var MinkContext
30
	 */
31
	protected $minkContext;
32
	
33
	static private $jobCategoryChecked = false;
34
	
35
	/**
36
	 * @BeforeScenario
37
	 * @param BeforeScenarioScope $scope
38
	 */
39
	public function gatherContexts(BeforeScenarioScope $scope)
40
	{
41
		$this->minkContext = $scope->getEnvironment()->getContext(MinkContext::class);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Behat\Testwork\Environment\Environment as the method getContext() does only exist in the following implementations of said interface: Behat\Behat\Context\Envi...lizedContextEnvironment, FriendsOfBehat\ContextSe...ntextServiceEnvironment.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
42
		if(false === static::$jobCategoryChecked){
0 ignored issues
show
Bug introduced by
Since $jobCategoryChecked is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $jobCategoryChecked to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
43
			/* @var Categories $catRepo */
44
			$catRepo = $this->getRepositories()->get('Jobs/Category');
45
			$all = $catRepo->findAll();
46
			if(count($all) <= 1){
47
				$catRepo->createDefaultCategory('professions');
48
				$catRepo->createDefaultCategory('industries');
49
				$catRepo->createDefaultCategory('employmentTypes');
50
			}
51
			static::$jobCategoryChecked = true;
0 ignored issues
show
Bug introduced by
Since $jobCategoryChecked is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $jobCategoryChecked to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
52
		}
53
	}
54
	
55
	/**
56
	 * @return Application
57
	 */
58
	public function getApplication()
59
	{
60
		if(!is_object(static::$application)){
61
			$configFile = realpath(__DIR__.'/../../../config/config.php');
62
			$config = include($configFile);
63
			static::$application = Application::init($config);
64
		}
65
		return static::$application;
66
	}
67
	
68
	/**
69
	 * @return \Zend\ServiceManager\ServiceManager
70
	 */
71
	public function getServiceManager()
72
	{
73
		return $this->getApplication()->getServiceManager();
74
	}
75
	
76
	/**
77
	 * @return \Zend\EventManager\EventManagerInterface
78
	 */
79
	public function getEventManager()
80
	{
81
		return $this->getApplication()->getEventManager();
82
	}
83
	
84
	/**
85
	 * @return RepositoryService
86
	 */
87
	public function getRepositories()
88
	{
89
		return $this->getServiceManager()->get('repositories');
90
	}
91
	
92
	/**
93
	 * @param $name
94
	 * @param array $params
0 ignored issues
show
Bug introduced by
There is no parameter named $params. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
95
	 *
96
	 * @return string
97
	 */
98
	public function generateUrl($name)
99
	{
100
		return $this->minkContext->locatePath($name);
101
	}
102
	
103
	/**
104
	 * @When /^I hover over the element "([^"]*)"$/
105
	 */
106
	public function iHoverOverTheElement($locator)
107
	{
108
		$session = $this->minkContext->getSession(); // get the mink session
109
		$element = $session->getPage()->find('css', $locator); // runs the actual query and returns the element
110
		
111
		// errors must not pass silently
112
		if (null === $element) {
113
			throw new \InvalidArgumentException(sprintf('Could not evaluate CSS selector: "%s"', $locator));
114
		}
115
		
116
		// ok, let's hover it
117
		$element->mouseOver();
118
	}
119
	
120
	/**
121
	 * @Given /^I wait for (\d+) seconds$/
122
	 */
123
	public function iWaitForSecond($second)
124
	{
125
		sleep($second);
126
	}
127
	
128
	/**
129
	 * @Then /^I wait for the ajax response$/
130
	 */
131
	public function iWaitForTheAjaxResponse()
132
	{
133
		$this->getSession()->wait(5000, '(0 === jQuery.active)');
134
	}
135
	
136
	/**
137
	 * Some forms do not have a Submit button just pass the ID
138
	 *
139
	 * @Given /^I submit the form with id "([^"]*)"$/
140
	 */
141
	public function iSubmitTheFormWithId($arg)
142
	{
143
		$node = $this->minkContext->getSession()->getPage()->find('css', $arg);
144
		if($node) {
145
			$this->minkContext->getSession()->executeScript("jQuery('$arg').submit();");
146
		} else {
147
			throw new \Exception('Element not found');
148
		}
149
	}
150
	
151
	/**
152
	 * @Then I switch to popup :name
153
	 *
154
	 * @param $name
155
	 */
156
	public function iSwitchToPopup($name)
157
	{
158
		$this->iSetMainWindowName();
159
		$this->getSession()->switchToWindow($name);
160
	}
161
	
162
	/**
163
	 * @Then I set main window name
164
	 */
165
	public function iSetMainWindowName()
166
	{
167
		$window_name = 'main_window';
0 ignored issues
show
Coding Style introduced by
$window_name does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
168
		$script = 'window.name = "' . $window_name . '"';
0 ignored issues
show
Coding Style introduced by
$window_name does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
169
		$this->getSession()->executeScript($script);
170
	}
171
	
172
	/**
173
	 * @Then I switch back to main window
174
	 */
175
	public function iSwitchBackToMainWindow()
176
	{
177
		$this->getSession()->switchToWindow('main_window');
178
	}
179
	
180
	public function iVisit($url)
181
	{
182
		$this->minkContext->getSession()->visit($url);
183
	}
184
	
185
	/**
186
	 * @When I scroll :selector into view
187
	 *
188
	 * @param string $selector Allowed selectors: #id, .className, //xpath
189
	 *
190
	 * @throws \Exception
191
	 */
192
	public function scrollIntoView($selector)
193
	{
194
		$locator = substr($selector, 0, 1);
195
		
196
		switch ($locator) {
197
			case '/' : // XPath selector
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
198
				$function = <<<JS
199
(function(){
200
  var elem = document.evaluate($selector, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
201
  elem.scrollIntoView(false);
202
})()
203
JS;
204
				break;
205
			
206
			case '#' : // ID selector
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
207
				$selector = substr($selector, 1);
208
				$function = <<<JS
209
(function(){
210
  var elem = document.getElementById("$selector");
211
  elem.scrollIntoView(false);
212
})()
213
JS;
214
				break;
215
			
216
			case '.' : // Class selector
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
217
				$selector = substr($selector, 1);
218
				$function = <<<JS
219
(function(){
220
  var elem = document.getElementsByClassName("$selector");
221
  elem[0].scrollIntoView(false);
222
})()
223
JS;
224
				break;
225
			
226
			default:
227
				throw new \Exception(__METHOD__ . ' Couldn\'t find selector: ' . $selector . ' - Allowed selectors: #id, .className, //xpath');
228
				break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
229
		}
230
		
231
		try {
232
			$this->getSession()->executeScript($function);
233
		} catch (\Exception $e) {
234
			throw new \Exception(__METHOD__ . ' failed'. ' Message: for this locator:"'.$selector.'"');
235
		}
236
	}
237
	
238
	
239
	/**
240
	 * @When I click location selector
241
	 */
242
	public function iClickLocationSelector()
243
	{
244
		$locator = '#jobBase-geoLocation-span .select2';
245
		$element = $this->getElement($locator);
246
		$element->click();
247
	}
248
	
249
	/**
250
	 * @param $locator
251
	 * @param string $selector
252
	 *
253
	 * @return \Behat\Mink\Element\NodeElement|mixed|null
254
	 */
255
	public function getElement($locator,$selector='css')
256
	{
257
		$page = $this->minkContext->getSession()->getPage();
258
		$element = $page->find('css',$locator);
259
		return $element;
260
	}
261
	
262
	/**
263
	 * @When I fill in location search with :term
264
	 * @param $term
265
	 */
266
	public function iFillInLocationSearch($term)
267
	{
268
		$locator = '.select2-container--open .select2-search__field';
269
		$element = $this->getElement($locator);
270
		$element->focus();
271
		$element->setValue($term);
272
		$this->iWaitForTheAjaxResponse();
273
	}
274
	
275
	public function iClickOn()
276
	{
277
	
278
	}
279
	
280
	/**
281
	 * Click some text
282
	 *
283
	 * @When /^I click on the text "([^"]*)"$/
284
	 */
285
	public function iClickOnTheText($text)
286
	{
287
		$session = $this->getSession();
288
		$element = $session->getPage()->find(
289
			'xpath',
290
			$session->getSelectorsHandler()->selectorToXpath('xpath', '*//*[text()="'. $text .'"]')
291
		);
292
		if(null === $element){
293
			$element = $session->getPage()->find(
294
				'named',
295
				array('id',$text)
296
			);
297
		}
298
		if (null === $element) {
299
			throw new \InvalidArgumentException(sprintf('Cannot find text: "%s"', $text));
300
		}
301
		
302
		$element->click();
303
		
304
	}
305
	
306
}