/** * Performs calling "magic" methods from annotations. * * For example, annotation `method SomePage clickFoo()` defines a magic * method that calls `$this->foo->click()` and returns an object of type * `SomePage`. If `$this` is instance of that type, it will return `$this`. * Otherwise it instantiates a new object. * * Either way it calls the method {@see self::checkState()} afterwise on the * return object. * * The annotation may contain more return types, separated by vertical bar. * First that match is returned back. * * Another magic method is fillShortcut - if it is defined such a shortcut, * it will translate to `$this->shortcut->value($input)`, but it returns * `$this`. * * @param string $name Name of called method. * @param array $args * @return mixed */ public function __call($name, $args) { if (!isset($this->methods)) { foreach ($this->getThisClasses() as $className) { $annotations = Utils::getClassAnnotations($className); $methodAnnotations = isset($annotations['method']) ? $annotations['method'] : array(); foreach ($methodAnnotations as $methodAnnotation) { if (preg_match('~^(?<type>[^\\s]+)\\s+(?<methodName>[^\\s(]+)~', $methodAnnotation, $matches)) { $returnType = $matches['type']; $fullMethodName = $matches['methodName']; if (preg_match('~^(?<elementMethod>[[:lower:]]+)(?<elementShortcut>.*)~', $fullMethodName, $matches)) { $elementMethod = $matches['elementMethod']; $elementShortcut = isset($this->{$matches['elementShortcut']}) ? $matches['elementShortcut'] : lcfirst($matches['elementShortcut']); if (isset($this->{$elementShortcut})) { $this->methods[$fullMethodName] = array($elementShortcut, $elementMethod, $returnType, $className); } } } } } } if (isset($this->methods[$name])) { $elementShortcut = $this->methods[$name][0]; $elementMethod = $this->methods[$name][1]; callback($this->{$elementShortcut}, $elementMethod)->invokeArgs($args); $this->session->waitForDocument(); return $this->getNextPageFromList(explode('|', $this->methods[$name][2]), $this->methods[$name][3]); } elseif (substr($name, 0, 4) === 'fill' && (isset($this->{$shortcut = substr($name, 4)}) || isset($this->{$shortcut = lcfirst(substr($name, 4))}))) { callback($this->{$shortcut}, 'value')->invokeArgs($args); return $this; } else { return parent::__call($name, $args); } }
/** * Closes the session. Keeps the session open on failure. * * Note that the session closes itself anyway after while. But if you're * close to the computer that runs the test, it may help you to see what * exactly happened on the gorram tested page. */ protected function tearDown() { parent::tearDown(); if ($this->session && $this->keepOpenOnFailure && $this->getStatus() !== \PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) { $this->session->keepOpen(); } if ($this->session) { $this->session->stop(); } }