From 20d7733459b9d85583ae0268573f611f4b7764f1 Mon Sep 17 00:00:00 2001 From: Gintautas Miselis Date: Sat, 5 Dec 2020 21:42:12 +0200 Subject: [PATCH 01/26] Change codeception version constraint to fix codeception builds on PHP 8 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 236406e..d8108d9 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "php": ">=5.6.0 <9.0", "guzzlehttp/guzzle": "^6.3|^7.0", "codeception/lib-innerbrowser": "^1.3", - "codeception/codeception": "^4.0" + "codeception/codeception": "*@dev" }, "require-dev": { "codeception/module-rest": "^1.0" From f76a729ecc549322bbb0b7a6bc564256ad9ac5e8 Mon Sep 17 00:00:00 2001 From: Gintautas Miselis Date: Tue, 29 Dec 2020 20:16:46 +0200 Subject: [PATCH 02/26] Replace Codeception\Util\Stub with Codeception\Stub in tests --- tests/unit/Codeception/Module/PhpBrowserRestTest.php | 4 ++-- tests/unit/Codeception/Module/PhpBrowserTest.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/Codeception/Module/PhpBrowserRestTest.php b/tests/unit/Codeception/Module/PhpBrowserRestTest.php index b3f63c7..58b85f0 100644 --- a/tests/unit/Codeception/Module/PhpBrowserRestTest.php +++ b/tests/unit/Codeception/Module/PhpBrowserRestTest.php @@ -1,7 +1,7 @@ phpBrowser = new \Codeception\Module\PhpBrowser($container); $url = 'http://localhost:8010'; $this->phpBrowser->_setConfig(['url' => $url]); diff --git a/tests/unit/Codeception/Module/PhpBrowserTest.php b/tests/unit/Codeception/Module/PhpBrowserTest.php index 7ff5740..150ab80 100644 --- a/tests/unit/Codeception/Module/PhpBrowserTest.php +++ b/tests/unit/Codeception/Module/PhpBrowserTest.php @@ -1,7 +1,7 @@ module = new \Codeception\Module\PhpBrowser($container); $url = 'http://localhost:8000'; $this->module->_setConfig(['url' => $url]); From a0ba85825a3777a7bc3e0b10c529c5569a1cf4cc Mon Sep 17 00:00:00 2001 From: Tavo Nieves J <64917965+TavoNiievez@users.noreply.github.com> Date: Tue, 12 Jan 2021 15:00:38 -0500 Subject: [PATCH 03/26] Standardize the `README` format (#10) --- readme.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/readme.md b/readme.md index 7aa111b..b12122d 100644 --- a/readme.md +++ b/readme.md @@ -1,15 +1,24 @@ -# PhpBrowser +# Codeception Module PhpBrowser -Codeception module for testing web application over HTTP +A Codeception module for testing web application over HTTP. -![Build Status](https://github.com/Codeception/module-phpbrowser/workflows/CI/badge.svg) +[![Actions Status](https://github.com/Codeception/module-phpbrowser/workflows/CI/badge.svg)](https://github.com/Codeception/module-phpbrowser/actions) +[![Latest Stable Version](https://poser.pugx.org/codeception/module-phpbrowser/v/stable)](https://github.com/Codeception/module-phpbrowser/releases) +[![Total Downloads](https://poser.pugx.org/codeception/module-phpbrowser/downloads)](https://packagist.org/packages/codeception/module-phpbrowser) +[![License](https://poser.pugx.org/codeception/module-phpbrowser/license)](/LICENSE) ## Installation ``` -composer require --dev "codeception/module-phpbrowser" +composer require "codeception/module-phpbrowser" --dev ``` ## Documentation -Module documentation +See [the module documentation](https://codeception.com/docs/modules/PhpBrowser). + +## License + +`Codeception Module PhpBrowser` is open-sourced software licensed under the [MIT](/LICENSE) License. + +© Codeception PHP Testing Framework From e66eec9a324af9b72065f1409b0a539a83ec6d75 Mon Sep 17 00:00:00 2001 From: Tavo Nieves J <64917965+TavoNiievez@users.noreply.github.com> Date: Thu, 27 May 2021 14:54:00 -0500 Subject: [PATCH 04/26] Code standards updated to PHP 7.1 (#12) --- .github/workflows/main.yml | 2 +- composer.json | 74 ++++++------ readme.md | 4 + src/Codeception/Lib/Connector/Guzzle.php | 110 ++++++++++-------- src/Codeception/Module/PhpBrowser.php | 32 ++--- .../Codeception/Module/PhpBrowserRestTest.php | 4 +- .../Codeception/Module/PhpBrowserTest.php | 6 +- .../Codeception/Module/TestsForBrowsers.php | 3 + tests/unit/Codeception/Module/TestsForWeb.php | 3 + 9 files changed, 135 insertions(+), 103 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0e8081c..0a77212 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: - php: [5.6, 7.0, 7.1, 7.2, 7.3, 7.4, 8.0] + php: [7.1, 7.2, 7.3, 7.4, 8.0] steps: - name: Checkout code diff --git a/composer.json b/composer.json index d8108d9..b4d69e0 100644 --- a/composer.json +++ b/composer.json @@ -1,38 +1,40 @@ { - "name":"codeception/module-phpbrowser", - "description":"Codeception module for testing web application over HTTP", - "keywords":["codeception", "http", "functional-testing"], - "homepage":"http://codeception.com/", - "type":"library", - "license":"MIT", - "authors":[ - { - "name":"Michael Bodnarchuk" - }, - { - "name":"Gintautas Miselis" - } - ], - "minimum-stability": "RC", - "require": { - "php": ">=5.6.0 <9.0", - "guzzlehttp/guzzle": "^6.3|^7.0", - "codeception/lib-innerbrowser": "^1.3", - "codeception/codeception": "*@dev" - }, - "require-dev": { - "codeception/module-rest": "^1.0" - }, - "conflict": { - "codeception/codeception": "<4.0" - }, - "suggest": { - "codeception/phpbuiltinserver": "Start and stop PHP built-in web server for your tests" - }, - "autoload":{ - "classmap": ["src/"] - }, - "config": { - "classmap-authoritative": true - } + "name": "codeception/module-phpbrowser", + "description": "Codeception module for testing web application over HTTP", + "keywords": [ "codeception", "http", "functional-testing" ], + "homepage": "https://codeception.com/", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Michael Bodnarchuk" + }, + { + "name": "Gintautas Miselis" + } + ], + "minimum-stability": "RC", + "require": { + "php": "^7.1 || ^8.0", + "guzzlehttp/guzzle": "^6.3|^7.0", + "codeception/lib-innerbrowser": "^1.3", + "codeception/codeception": "*@dev" + }, + "require-dev": { + "codeception/module-rest": "^1.0" + }, + "conflict": { + "codeception/codeception": "<4.0" + }, + "suggest": { + "codeception/phpbuiltinserver": "Start and stop PHP built-in web server for your tests" + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "config": { + "classmap-authoritative": true + } } diff --git a/readme.md b/readme.md index b12122d..c5de470 100644 --- a/readme.md +++ b/readme.md @@ -7,6 +7,10 @@ A Codeception module for testing web application over HTTP. [![Total Downloads](https://poser.pugx.org/codeception/module-phpbrowser/downloads)](https://packagist.org/packages/codeception/module-phpbrowser) [![License](https://poser.pugx.org/codeception/module-phpbrowser/license)](/LICENSE) +## Requirements + +* `PHP 7.1` or higher. + ## Installation ``` diff --git a/src/Codeception/Lib/Connector/Guzzle.php b/src/Codeception/Lib/Connector/Guzzle.php index 7d68629..d8b0064 100644 --- a/src/Codeception/Lib/Connector/Guzzle.php +++ b/src/Codeception/Lib/Connector/Guzzle.php @@ -1,4 +1,7 @@ false, 'headers' => [], ]; + + /** + * @var int + */ protected $refreshMaxInterval = 0; + /** + * @var \Aws\Credentials\Credentials|null + */ protected $awsCredentials; + + /** + * @var \Aws\Signature\SignatureV4|null + */ protected $awsSignature; - /** @var GuzzleClient */ + /** + * @var GuzzleClient + */ protected $client; /** @@ -43,14 +62,14 @@ class Guzzle extends Client * * @param int $seconds Number of seconds */ - public function setRefreshMaxInterval($seconds) + public function setRefreshMaxInterval(int $seconds): void { $this->refreshMaxInterval = $seconds; } - public function setClient(GuzzleClient $client) + public function setClient(GuzzleClient $guzzleClient): void { - $this->client = $client; + $this->client = $guzzleClient; } /** @@ -63,9 +82,9 @@ public function setClient(GuzzleClient $client) * @param string $name the name of the header * @param string $value the value of the header */ - public function setHeader($name, $value) + public function setHeader(string $name, string $value): void { - if ((string)$value === '') { + if ($value === '') { $this->deleteHeader($name); } else { $this->requestOptions['headers'][$name] = $value; @@ -78,19 +97,14 @@ public function setHeader($name, $value) * * @param string $name the name of the header to delete. */ - public function deleteHeader($name) + public function deleteHeader(string $name): void { unset($this->requestOptions['headers'][$name]); } - /** - * @param string $username - * @param string $password - * @param string $type Default: 'basic' - */ - public function setAuth($username, $password, $type = 'basic') + public function setAuth(string $username, string $password, string $type = 'basic'): void { - if (!$username) { + if ($username === '') { unset($this->requestOptions['auth']); return; } @@ -100,14 +114,12 @@ public function setAuth($username, $password, $type = 'basic') /** * Taken from Mink\BrowserKitDriver * - * @param Psr7Response $response - * * @return BrowserKitResponse */ - protected function createResponse(Psr7Response $response) + protected function createResponse(Psr7Response $psr7Response): BrowserKitResponse { - $body = (string) $response->getBody(); - $headers = $response->getHeaders(); + $body = (string) $psr7Response->getBody(); + $headers = $psr7Response->getHeaders(); $contentType = null; @@ -119,18 +131,18 @@ protected function createResponse(Psr7Response $response) } if (strpos($contentType, 'charset=') === false) { - if (preg_match('/]+charset *= *["\']?([a-zA-Z\-0-9]+)/i', $body, $matches)) { + if (preg_match('#]+charset *= *["\']?([a-zA-Z\-0-9]+)#i', $body, $matches)) { $contentType .= ';charset=' . $matches[1]; } $headers['Content-Type'] = [$contentType]; } - $status = $response->getStatusCode(); + $status = $psr7Response->getStatusCode(); if ($status < 300 || $status >= 400) { $matches = []; $matchesMeta = preg_match( - '/]+http-equiv="refresh" content="\s*(\d*)\s*;\s*url=(.*?)"/i', + '#]+http-equiv="refresh" content="\s*(\d*)\s*;\s*url=(.*?)"#i', $body, $matches ); @@ -138,7 +150,7 @@ protected function createResponse(Psr7Response $response) if (!$matchesMeta && isset($headers['Refresh'])) { // match by header preg_match( - '/^\s*(\d*)\s*;\s*url=(.*)/i', + '#^\s*(\d*)\s*;\s*url=(.*)#i', (string) reset($headers['Refresh']), $matches ); @@ -150,7 +162,7 @@ protected function createResponse(Psr7Response $response) if ($uri->withFragment('') !== $currentUri->withFragment('')) { $status = 302; - $headers['Location'] = $matchesMeta ? htmlspecialchars_decode($uri) : (string)$uri; + $headers['Location'] = $matchesMeta ? htmlspecialchars_decode((string) $uri) : (string)$uri; } } } @@ -158,7 +170,7 @@ protected function createResponse(Psr7Response $response) return new BrowserKitResponse($body, $status, $headers); } - public function getAbsoluteUri($uri) + protected function getAbsoluteUri($uri) { $baseUri = $this->client->getConfig('base_uri'); if (strpos($uri, '://') === false && strpos($uri, '//') !== 0) { @@ -172,7 +184,7 @@ public function getAbsoluteUri($uri) } // relative url if (!$this->getHistory()->isEmpty()) { - return Uri::mergeUrls((string)$this->getHistory()->current()->getUri(), $uri); + return Uri::mergeUrls($this->getHistory()->current()->getUri(), $uri); } } return Uri::mergeUrls($baseUri, $uri); @@ -214,7 +226,7 @@ protected function doRequest($request) return $this->createResponse($response); } - protected function extractHeaders(BrowserKitRequest $request) + protected function extractHeaders(BrowserKitRequest $request): array { $headers = []; $server = $request->getServer(); @@ -231,39 +243,37 @@ protected function extractHeaders(BrowserKitRequest $request) return $headers; } - protected function extractFormData(BrowserKitRequest $request) + protected function extractFormData(BrowserKitRequest $browserKitRequest): ?array { - if (!in_array(strtoupper($request->getMethod()), ['POST', 'PUT', 'PATCH', 'DELETE'])) { + if (!in_array(strtoupper($browserKitRequest->getMethod()), ['POST', 'PUT', 'PATCH', 'DELETE'])) { return null; } // guessing if it is a form data - $headers = $request->getServer(); - if (isset($headers['HTTP_CONTENT_TYPE'])) { - // not a form - if ($headers['HTTP_CONTENT_TYPE'] !== 'application/x-www-form-urlencoded') { - return null; - } + $headers = $browserKitRequest->getServer(); + // not a form + if (isset($headers['HTTP_CONTENT_TYPE']) && $headers['HTTP_CONTENT_TYPE'] !== 'application/x-www-form-urlencoded') { + return null; } - if ($request->getContent() !== null) { + if ($browserKitRequest->getContent() !== null) { return null; } - return $request->getParameters(); + return $browserKitRequest->getParameters(); } - protected function extractMultipartFormData(BrowserKitRequest $request) + protected function extractMultipartFormData(BrowserKitRequest $browserKitRequest) { - if (!in_array(strtoupper($request->getMethod()), ['POST', 'PUT', 'PATCH'])) { + if (!in_array(strtoupper($browserKitRequest->getMethod()), ['POST', 'PUT', 'PATCH'])) { return []; } - $parts = $this->mapFiles($request->getFiles()); + $parts = $this->mapFiles($browserKitRequest->getFiles()); if (empty($parts)) { return []; } - foreach ($request->getParameters() as $k => $v) { - $parts = $this->formatMultipart($parts, $k, $v); + foreach ($browserKitRequest->getParameters() as $k => $parameter) { + $parts = $this->formatMultipart($parts, $k, $parameter); } return $parts; } @@ -272,7 +282,7 @@ protected function formatMultipart($parts, $key, $value) { if (is_array($value)) { foreach ($value as $subKey => $subValue) { - $parts = array_merge($this->formatMultipart([], $key."[$subKey]", $subValue), $parts); + $parts = array_merge($this->formatMultipart([], $key.sprintf('[%s]', $subKey), $subValue), $parts); } return $parts; } @@ -280,7 +290,7 @@ protected function formatMultipart($parts, $key, $value) return $parts; } - protected function mapFiles($requestFiles, $arrayName = '') + protected function mapFiles($requestFiles, $arrayName = ''): array { $files = []; foreach ($requestFiles as $name => $info) { @@ -292,7 +302,7 @@ protected function mapFiles($requestFiles, $arrayName = '') if (isset($info['tmp_name'])) { if ($info['tmp_name']) { $handle = fopen($info['tmp_name'], 'rb'); - $filename = isset($info['name']) ? $info['name'] : null; + $filename = $info['name'] ?? null; $file = [ 'name' => $name, 'contents' => $handle, @@ -319,7 +329,7 @@ protected function mapFiles($requestFiles, $arrayName = '') return $files; } - protected function extractCookies($host) + protected function extractCookies($host): \GuzzleHttp\Cookie\CookieJar { $jar = []; $cookies = $this->getCookieJar()->all(); @@ -333,7 +343,7 @@ protected function extractCookies($host) return new CookieJar(false, $jar); } - public static function createHandler($handler) + public static function createHandler($handler): \GuzzleHttp\HandlerStack { if ($handler instanceof HandlerStack) { return $handler; @@ -353,7 +363,7 @@ public static function createHandler($handler) return HandlerStack::create(); } - public function setAwsAuth($config) + public function setAwsAuth($config): void { $this->awsCredentials = new Credentials($config['key'], $config['secret']); $this->awsSignature = new SignatureV4($config['service'], $config['region']); diff --git a/src/Codeception/Module/PhpBrowser.php b/src/Codeception/Module/PhpBrowser.php index bbf2ce8..abcd394 100644 --- a/src/Codeception/Module/PhpBrowser.php +++ b/src/Codeception/Module/PhpBrowser.php @@ -1,4 +1,7 @@ [], 'verify' => false, @@ -95,6 +103,9 @@ class PhpBrowser extends InnerBrowser implements Remote, MultiSession 'cookies' => true, ]; + /** + * @var string[] + */ protected $guzzleConfigFields = [ 'auth', 'proxy', @@ -139,21 +150,18 @@ public function _getUrl() /** * Alias to `haveHttpHeader` - * - * @param $name - * @param $value */ - public function setHeader($name, $value) + public function setHeader(string $name, string $value): void { $this->haveHttpHeader($name, $value); } - public function amHttpAuthenticated($username, $password) + public function amHttpAuthenticated($username, $password): void { $this->client->setAuth($username, $password); } - public function amOnUrl($url) + public function amOnUrl($url): void { $host = Uri::retrieveHost($url); $config = $this->config; @@ -167,11 +175,12 @@ public function amOnUrl($url) $this->amOnPage($page); } - public function amOnSubdomain($subdomain) + public function amOnSubdomain($subdomain): void { $url = $this->config['url']; - $url = preg_replace('~(https?://)(.*\.)(.*\.)~', "$1$3", $url); // removing current subdomain - $url = preg_replace('~(https?://)(.*)~', "$1$subdomain.$2", $url); // inserting new + $url = preg_replace('#(https?://)(.*\.)(.*\.)#', "$1$3", $url); // removing current subdomain + $url = preg_replace('#(https?://)(.*)#', sprintf('$1%s.$2', $subdomain), $url); + // inserting new $config = $this->config; $config['url'] = $url; $this->_reconfigure($config); @@ -193,13 +202,11 @@ protected function onReconfigure() * $I->executeInGuzzle(function (\GuzzleHttp\Client $client) { * $client->get('/get', ['query' => ['foo' => 'bar']]); * }); - * ?> * ``` * * It is not recommended to use this command on a regular basis. * If Codeception lacks important Guzzle Client methods, implement them and submit patches. * - * @param Closure $function * @return mixed */ public function executeInGuzzle(Closure $function) @@ -207,7 +214,6 @@ public function executeInGuzzle(Closure $function) return $function($this->guzzle); } - public function _getResponseCode() { return $this->getResponseStatusCode(); diff --git a/tests/unit/Codeception/Module/PhpBrowserRestTest.php b/tests/unit/Codeception/Module/PhpBrowserRestTest.php index 58b85f0..a86a6eb 100644 --- a/tests/unit/Codeception/Module/PhpBrowserRestTest.php +++ b/tests/unit/Codeception/Module/PhpBrowserRestTest.php @@ -1,9 +1,11 @@ module->seeResponseCodeIs(200); $this->module->dontSee('Unauthorized'); $this->module->see("Welcome, davert"); - $this->module->amHttpAuthenticated(null, null); + $this->module->amHttpAuthenticated('', ''); $this->module->amOnPage('/auth'); $this->module->seeResponseCodeIs(401); $this->module->amHttpAuthenticated('davert', '123456'); diff --git a/tests/unit/Codeception/Module/TestsForBrowsers.php b/tests/unit/Codeception/Module/TestsForBrowsers.php index bbf3b55..d0df175 100644 --- a/tests/unit/Codeception/Module/TestsForBrowsers.php +++ b/tests/unit/Codeception/Module/TestsForBrowsers.php @@ -1,4 +1,7 @@ Date: Sun, 6 Jun 2021 19:51:44 +0300 Subject: [PATCH 05/26] Cast uri to string (#14) This casting was removed by modernization PR #12 It is necessary to fix Codeception 5 build. --- src/Codeception/Lib/Connector/Guzzle.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Codeception/Lib/Connector/Guzzle.php b/src/Codeception/Lib/Connector/Guzzle.php index d8b0064..bd50f95 100644 --- a/src/Codeception/Lib/Connector/Guzzle.php +++ b/src/Codeception/Lib/Connector/Guzzle.php @@ -184,7 +184,7 @@ protected function getAbsoluteUri($uri) } // relative url if (!$this->getHistory()->isEmpty()) { - return Uri::mergeUrls($this->getHistory()->current()->getUri(), $uri); + return Uri::mergeUrls((string)$this->getHistory()->current()->getUri(), $uri); } } return Uri::mergeUrls($baseUri, $uri); From 871bc5b536c04cbb7a60d6d583da2af5f5921df7 Mon Sep 17 00:00:00 2001 From: Gintautas Miselis Date: Sun, 6 Jun 2021 20:07:15 +0300 Subject: [PATCH 06/26] Cast another uri to string --- src/Codeception/Lib/Connector/Guzzle.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Codeception/Lib/Connector/Guzzle.php b/src/Codeception/Lib/Connector/Guzzle.php index bd50f95..762cdf3 100644 --- a/src/Codeception/Lib/Connector/Guzzle.php +++ b/src/Codeception/Lib/Connector/Guzzle.php @@ -187,7 +187,7 @@ protected function getAbsoluteUri($uri) return Uri::mergeUrls((string)$this->getHistory()->current()->getUri(), $uri); } } - return Uri::mergeUrls($baseUri, $uri); + return Uri::mergeUrls((string)$baseUri, $uri); } protected function doRequest($request) From 9815cb97f05d322d2df3c9d85661c68fc78e9848 Mon Sep 17 00:00:00 2001 From: Tavo Nieves J <64917965+TavoNiievez@users.noreply.github.com> Date: Sun, 6 Jun 2021 21:21:24 -0500 Subject: [PATCH 07/26] Support for Codeception 5 (#13) --- .github/workflows/main.yml | 2 +- composer.json | 13 +++++++------ readme.md | 2 +- src/Codeception/Lib/Connector/Guzzle.php | 2 +- src/Codeception/Module/PhpBrowser.php | 8 ++++---- .../unit/Codeception/Module/PhpBrowserRestTest.php | 4 ++-- 6 files changed, 16 insertions(+), 15 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0a77212..3e53396 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: - php: [7.1, 7.2, 7.3, 7.4, 8.0] + php: [7.3, 7.4, 8.0] steps: - name: Checkout code diff --git a/composer.json b/composer.json index b4d69e0..0e20ed2 100644 --- a/composer.json +++ b/composer.json @@ -15,16 +15,17 @@ ], "minimum-stability": "RC", "require": { - "php": "^7.1 || ^8.0", - "guzzlehttp/guzzle": "^6.3|^7.0", - "codeception/lib-innerbrowser": "^1.3", - "codeception/codeception": "*@dev" + "php": "^7.3 || ^8.0", + "ext-json": "*", + "guzzlehttp/guzzle": "^7.3", + "codeception/lib-innerbrowser": "^1.5 || *@dev", + "codeception/codeception": "^5.0 || *@dev" }, "require-dev": { - "codeception/module-rest": "^1.0" + "codeception/module-rest": "^1.3 || *@dev" }, "conflict": { - "codeception/codeception": "<4.0" + "codeception/codeception": "<5.0" }, "suggest": { "codeception/phpbuiltinserver": "Start and stop PHP built-in web server for your tests" diff --git a/readme.md b/readme.md index c5de470..ea338c4 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,7 @@ A Codeception module for testing web application over HTTP. ## Requirements -* `PHP 7.1` or higher. +* `PHP 7.3` or higher. ## Installation diff --git a/src/Codeception/Lib/Connector/Guzzle.php b/src/Codeception/Lib/Connector/Guzzle.php index 762cdf3..86cc662 100644 --- a/src/Codeception/Lib/Connector/Guzzle.php +++ b/src/Codeception/Lib/Connector/Guzzle.php @@ -176,7 +176,7 @@ protected function getAbsoluteUri($uri) if (strpos($uri, '://') === false && strpos($uri, '//') !== 0) { if (strpos($uri, '/') === 0) { $baseUriPath = $baseUri->getPath(); - if (!empty($baseUriPath) && strpos($uri, $baseUriPath) === 0) { + if (!empty($baseUriPath) && strpos($uri, (string) $baseUriPath) === 0) { $uri = substr($uri, strlen($baseUriPath)); } diff --git a/src/Codeception/Module/PhpBrowser.php b/src/Codeception/Module/PhpBrowser.php index abcd394..4755dce 100644 --- a/src/Codeception/Module/PhpBrowser.php +++ b/src/Codeception/Module/PhpBrowser.php @@ -219,7 +219,7 @@ public function _getResponseCode() return $this->getResponseStatusCode(); } - public function _initializeSession() + public function _initializeSession(): void { // independent sessions need independent cookies $this->client = new Guzzle(); @@ -255,7 +255,7 @@ public function _prepareSession() $this->client->setClient($this->guzzle); } - public function _backupSession() + public function _backupSession(): array { return [ 'client' => $this->client, @@ -265,14 +265,14 @@ public function _backupSession() ]; } - public function _loadSession($session) + public function _loadSession($session): void { foreach ($session as $key => $val) { $this->$key = $val; } } - public function _closeSession($session = null) + public function _closeSession($session = null): void { unset($session); } diff --git a/tests/unit/Codeception/Module/PhpBrowserRestTest.php b/tests/unit/Codeception/Module/PhpBrowserRestTest.php index a86a6eb..49f037a 100644 --- a/tests/unit/Codeception/Module/PhpBrowserRestTest.php +++ b/tests/unit/Codeception/Module/PhpBrowserRestTest.php @@ -133,13 +133,13 @@ public function testArrayJson() public function testSeeResponseContainsJsonFailsGracefullyWhenJsonResultIsNotArray() { $this->shouldFail(); - $this->setStubResponse(json_encode('no_status')); + $this->setStubResponse(json_encode('no_status', JSON_THROW_ON_ERROR)); $this->module->seeResponseContainsJson(array('id' => 1)); } public function testDontSeeResponseJsonMatchesJsonPathPassesWhenJsonResultIsNotArray() { - $this->setStubResponse(json_encode('no_status')); + $this->setStubResponse(json_encode('no_status', JSON_THROW_ON_ERROR)); $this->module->dontSeeResponseJsonMatchesJsonPath('$.error'); } From b6fa20b65dbe484850197a4487ca9b050ced0fd9 Mon Sep 17 00:00:00 2001 From: Ihor Sychevskyi Date: Mon, 28 Jun 2021 03:26:15 +0300 Subject: [PATCH 08/26] Update readme.md (#16) --- readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readme.md b/readme.md index ea338c4..caa153a 100644 --- a/readme.md +++ b/readme.md @@ -21,6 +21,8 @@ composer require "codeception/module-phpbrowser" --dev See [the module documentation](https://codeception.com/docs/modules/PhpBrowser). +[Changelog](https://github.com/Codeception/module-phpbrowser/releases) + ## License `Codeception Module PhpBrowser` is open-sourced software licensed under the [MIT](/LICENSE) License. From e8865819455dd7a4099b9a18da435977564f16d6 Mon Sep 17 00:00:00 2001 From: TavoNiievez Date: Sun, 24 Oct 2021 17:59:20 -0500 Subject: [PATCH 09/26] Update codebase to PHP 7.4 --- .github/workflows/main.yml | 2 +- composer.json | 4 +- readme.md | 2 +- src/Codeception/Lib/Connector/Guzzle.php | 91 +++++----- src/Codeception/Module/PhpBrowser.php | 17 +- .../Codeception/Module/PhpBrowserRestTest.php | 81 ++++----- .../Codeception/Module/PhpBrowserTest.php | 91 ++++++---- .../Codeception/Module/TestsForBrowsers.php | 20 +-- tests/unit/Codeception/Module/TestsForWeb.php | 157 +++++++++++------- 9 files changed, 271 insertions(+), 194 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3e53396..c563b02 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: - php: [7.3, 7.4, 8.0] + php: [7.4, 8.0] steps: - name: Checkout code diff --git a/composer.json b/composer.json index 0e20ed2..629a0f0 100644 --- a/composer.json +++ b/composer.json @@ -15,13 +15,15 @@ ], "minimum-stability": "RC", "require": { - "php": "^7.3 || ^8.0", + "php": "^7.4 || ^8.0", "ext-json": "*", "guzzlehttp/guzzle": "^7.3", "codeception/lib-innerbrowser": "^1.5 || *@dev", "codeception/codeception": "^5.0 || *@dev" }, "require-dev": { + "ext-curl": "*", + "aws/aws-sdk-php": "^3.199", "codeception/module-rest": "^1.3 || *@dev" }, "conflict": { diff --git a/readme.md b/readme.md index caa153a..144cbb8 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,7 @@ A Codeception module for testing web application over HTTP. ## Requirements -* `PHP 7.3` or higher. +* `PHP 7.4` or higher. ## Installation diff --git a/src/Codeception/Lib/Connector/Guzzle.php b/src/Codeception/Lib/Connector/Guzzle.php index 86cc662..302f819 100644 --- a/src/Codeception/Lib/Connector/Guzzle.php +++ b/src/Codeception/Lib/Connector/Guzzle.php @@ -4,16 +4,16 @@ namespace Codeception\Lib\Connector; -use Aws\Credentials\Credentials; -use Aws\Signature\SignatureV4; +use Aws\Credentials\Credentials as AwsCredentials; +use Aws\Signature\SignatureV4 as AwsSignatureV4; use Codeception\Util\Uri; use GuzzleHttp\Client as GuzzleClient; -use GuzzleHttp\Cookie\CookieJar; +use GuzzleHttp\Cookie\CookieJar as GuzzleCookieJar; use GuzzleHttp\Cookie\SetCookie; use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Handler\CurlHandler; use GuzzleHttp\Handler\StreamHandler; -use GuzzleHttp\HandlerStack; +use GuzzleHttp\HandlerStack as GuzzleHandlerStack; use GuzzleHttp\Psr7\Request as Psr7Request; use GuzzleHttp\Psr7\Response as Psr7Response; use GuzzleHttp\Psr7\Uri as Psr7Uri; @@ -23,33 +23,18 @@ class Guzzle extends AbstractBrowser { - /** - * @var array - */ - protected $requestOptions = [ + protected array $requestOptions = [ 'allow_redirects' => false, 'headers' => [], ]; - /** - * @var int - */ - protected $refreshMaxInterval = 0; + protected int $refreshMaxInterval = 0; - /** - * @var \Aws\Credentials\Credentials|null - */ - protected $awsCredentials; + protected ?AwsCredentials $awsCredentials = null; - /** - * @var \Aws\Signature\SignatureV4|null - */ - protected $awsSignature; + protected ?AwsSignatureV4 $awsSignature = null; - /** - * @var GuzzleClient - */ - protected $client; + protected ?GuzzleClient $client = null; /** * Sets the maximum allowable timeout interval for a meta tag refresh to @@ -108,13 +93,12 @@ public function setAuth(string $username, string $password, string $type = 'basi unset($this->requestOptions['auth']); return; } + $this->requestOptions['auth'] = [$username, $password, $type]; } /** * Taken from Mink\BrowserKitDriver - * - * @return BrowserKitResponse */ protected function createResponse(Psr7Response $psr7Response): BrowserKitResponse { @@ -126,6 +110,7 @@ protected function createResponse(Psr7Response $psr7Response): BrowserKitRespons if (isset($headers['Content-Type'])) { $contentType = reset($headers['Content-Type']); } + if (!$contentType) { $contentType = 'text/html'; } @@ -134,6 +119,7 @@ protected function createResponse(Psr7Response $psr7Response): BrowserKitRespons if (preg_match('#]+charset *= *["\']?([a-zA-Z\-0-9]+)#i', $body, $matches)) { $contentType .= ';charset=' . $matches[1]; } + $headers['Content-Type'] = [$contentType]; } @@ -182,17 +168,19 @@ protected function getAbsoluteUri($uri) return Uri::appendPath((string)$baseUri, $uri); } + // relative url if (!$this->getHistory()->isEmpty()) { return Uri::mergeUrls((string)$this->getHistory()->current()->getUri(), $uri); } } + return Uri::mergeUrls((string)$baseUri, $uri); } protected function doRequest($request) { - /** @var $request BrowserKitRequest **/ + /** @var $request BrowserKitRequest **/ $guzzleRequest = new Psr7Request( $request->getMethod(), $request->getUri(), @@ -217,15 +205,20 @@ protected function doRequest($request) } else { $response = $this->client->send($guzzleRequest, $options); } - } catch (RequestException $e) { - if (!$e->hasResponse()) { - throw $e; + } catch (RequestException $exception) { + if (!$exception->hasResponse()) { + throw $exception; } - $response = $e->getResponse(); + + $response = $exception->getResponse(); } + return $this->createResponse($response); } + /** + * @return array + */ protected function extractHeaders(BrowserKitRequest $request): array { $headers = []; @@ -240,6 +233,7 @@ protected function extractHeaders(BrowserKitRequest $request): array $headers[$header] = $val; } } + return $headers; } @@ -255,9 +249,11 @@ protected function extractFormData(BrowserKitRequest $browserKitRequest): ?array if (isset($headers['HTTP_CONTENT_TYPE']) && $headers['HTTP_CONTENT_TYPE'] !== 'application/x-www-form-urlencoded') { return null; } + if ($browserKitRequest->getContent() !== null) { return null; } + return $browserKitRequest->getParameters(); } @@ -275,6 +271,7 @@ protected function extractMultipartFormData(BrowserKitRequest $browserKitRequest foreach ($browserKitRequest->getParameters() as $k => $parameter) { $parts = $this->formatMultipart($parts, $k, $parameter); } + return $parts; } @@ -284,8 +281,10 @@ protected function formatMultipart($parts, $key, $value) foreach ($value as $subKey => $subValue) { $parts = array_merge($this->formatMultipart([], $key.sprintf('[%s]', $subKey), $subValue), $parts); } + return $parts; } + $parts[] = ['name' => $key, 'contents' => (string) $value]; return $parts; } @@ -313,6 +312,7 @@ protected function mapFiles($requestFiles, $arrayName = ''): array 'content-type' => $info['type'] ]; } + $files[] = $file; } } else { @@ -329,7 +329,7 @@ protected function mapFiles($requestFiles, $arrayName = ''): array return $files; } - protected function extractCookies($host): \GuzzleHttp\Cookie\CookieJar + protected function extractCookies($host): GuzzleCookieJar { $jar = []; $cookies = $this->getCookieJar()->all(); @@ -338,34 +338,41 @@ protected function extractCookies($host): \GuzzleHttp\Cookie\CookieJar if (!$setCookie->getDomain()) { $setCookie->setDomain($host); } + $jar[] = $setCookie; } - return new CookieJar(false, $jar); + + return new GuzzleCookieJar(false, $jar); } - public static function createHandler($handler): \GuzzleHttp\HandlerStack + public static function createHandler($handler): GuzzleHandlerStack { - if ($handler instanceof HandlerStack) { + if ($handler instanceof GuzzleHandlerStack) { return $handler; } + if ($handler === 'curl') { - return HandlerStack::create(new CurlHandler()); + return GuzzleHandlerStack::create(new CurlHandler()); } + if ($handler === 'stream') { - return HandlerStack::create(new StreamHandler()); + return GuzzleHandlerStack::create(new StreamHandler()); } + if (is_string($handler) && class_exists($handler)) { - return HandlerStack::create(new $handler); + return GuzzleHandlerStack::create(new $handler); } + if (is_callable($handler)) { - return HandlerStack::create($handler); + return GuzzleHandlerStack::create($handler); } - return HandlerStack::create(); + + return GuzzleHandlerStack::create(); } public function setAwsAuth($config): void { - $this->awsCredentials = new Credentials($config['key'], $config['secret']); - $this->awsSignature = new SignatureV4($config['service'], $config['region']); + $this->awsCredentials = new AwsCredentials($config['key'], $config['secret']); + $this->awsSignature = new AwsSignatureV4($config['service'], $config['region']); } } diff --git a/src/Codeception/Module/PhpBrowser.php b/src/Codeception/Module/PhpBrowser.php index 4755dce..98ca7d0 100644 --- a/src/Codeception/Module/PhpBrowser.php +++ b/src/Codeception/Module/PhpBrowser.php @@ -14,7 +14,7 @@ use GuzzleHttp\Client as GuzzleClient; /** - * Uses [Guzzle](http://guzzlephp.org/) to interact with your application over CURL. + * Uses [Guzzle](https://docs.guzzlephp.org/en/stable/) to interact with your application over CURL. * Module works over CURL and requires **PHP CURL extension** to be enabled. * * Use to perform web acceptance tests with non-javascript browser. @@ -106,7 +106,7 @@ class PhpBrowser extends InnerBrowser implements Remote, MultiSession /** * @var string[] */ - protected $guzzleConfigFields = [ + protected array $guzzleConfigFields = [ 'auth', 'proxy', 'verify', @@ -125,10 +125,7 @@ class PhpBrowser extends InnerBrowser implements Remote, MultiSession */ public $client; - /** - * @var GuzzleClient - */ - public $guzzle; + public ?GuzzleClient $guzzle = null; public function _initialize() { @@ -140,6 +137,7 @@ public function _before(TestInterface $test) if (!$this->client) { $this->client = new Guzzle(); } + $this->_prepareSession(); } @@ -171,6 +169,7 @@ public function amOnUrl($url): void if ($page === '') { $page = '/'; } + $this->debugSection('Host', $host); $this->amOnPage($page); } @@ -214,6 +213,9 @@ public function executeInGuzzle(Closure $function) return $function($this->guzzle); } + /** + * @return int|string + */ public function _getResponseCode() { return $this->getResponseStatusCode(); @@ -226,7 +228,7 @@ public function _initializeSession(): void $this->_prepareSession(); } - public function _prepareSession() + public function _prepareSession(): void { $defaults = array_intersect_key($this->config, array_flip($this->guzzleConfigFields)); $curlOptions = []; @@ -248,6 +250,7 @@ public function _prepareSession() $handler->push($middleware); } } + $defaults['handler'] = $handler; $this->guzzle = new GuzzleClient($defaults); diff --git a/tests/unit/Codeception/Module/PhpBrowserRestTest.php b/tests/unit/Codeception/Module/PhpBrowserRestTest.php index 49f037a..e618375 100644 --- a/tests/unit/Codeception/Module/PhpBrowserRestTest.php +++ b/tests/unit/Codeception/Module/PhpBrowserRestTest.php @@ -2,42 +2,44 @@ declare(strict_types=1); +use Codeception\Lib\ModuleContainer; +use Codeception\Module\PhpBrowser; +use Codeception\Module\REST; +use Codeception\Test\Cest; use Codeception\Test\Unit; use Codeception\Stub; +use PHPUnit\Framework\AssertionFailedError; +use PHPUnit\Framework\ExpectationFailedException; +use Symfony\Component\BrowserKit\Request as SymfonyRequest; final class PhpBrowserRestTest extends Unit { - /** - * @var \Codeception\Module\REST - */ - protected $module; + protected REST $module; - /** - * @var \Codeception\Module\PhpBrowser - */ - protected $phpBrowser; + protected ?PhpBrowser $phpBrowser = null; - public function _setUp() + protected function _setUp() { - $container = Stub::make('Codeception\Lib\ModuleContainer'); - $this->phpBrowser = new \Codeception\Module\PhpBrowser($container); + $container = Stub::make(ModuleContainer::class); + $this->phpBrowser = new PhpBrowser($container); $url = 'http://localhost:8010'; $this->phpBrowser->_setConfig(['url' => $url]); $this->phpBrowser->_initialize(); - $this->module = Stub::make('\Codeception\Module\REST'); + $this->module = Stub::make(REST::class); $this->module->_inject($this->phpBrowser); $this->module->_initialize(); - $this->module->_before(Stub::makeEmpty('\Codeception\Test\Cest')); - $this->phpBrowser->_before(Stub::makeEmpty('\Codeception\Test\Cest')); + $this->module->_before(Stub::makeEmpty(Cest::class)); + + $this->phpBrowser->_before(Stub::makeEmpty(Cest::class)); } private function setStubResponse($response) { - $this->phpBrowser = Stub::make('\Codeception\Module\PhpBrowser', ['_getResponseContent' => $response]); + $this->phpBrowser = Stub::make(PhpBrowser::class, ['_getResponseContent' => $response]); $this->module->_inject($this->phpBrowser); $this->module->_initialize(); - $this->module->_before(Stub::makeEmpty('\Codeception\Test\Cest')); + $this->module->_before(Stub::makeEmpty(Cest::class)); } public function testGet() @@ -74,7 +76,7 @@ public function testValidJson() public function testInvalidJson() { - $this->expectException('PHPUnit\Framework\ExpectationFailedException'); + $this->expectException(ExpectationFailedException::class); $this->setStubResponse('{xxx = yyy}'); $this->module->seeResponseIsJson(); } @@ -90,7 +92,7 @@ public function testValidXml() public function testInvalidXml() { - $this->expectException('PHPUnit\Framework\ExpectationFailedException'); + $this->expectException(ExpectationFailedException::class); $this->setStubResponse('John'); $this->module->seeResponseIsXml(); } @@ -105,7 +107,7 @@ public function testSeeInJson() $this->module->seeResponseContainsJson(['user' => ['name' => 'Davert']]); $this->module->seeResponseContainsJson(['ticket' => ['title' => 'Bug should be fixed']]); $this->module->seeResponseContainsJson(['ticket' => ['user' => ['name' => 'Davert']]]); - $this->module->seeResponseContainsJson(array('ticket' => array('labels' => null))); + $this->module->seeResponseContainsJson(['ticket' => ['labels' => null]]); } public function testSeeInJsonCollection() @@ -115,8 +117,8 @@ public function testSeeInJsonCollection() . '{"user":"John Doe","age":27,"tags":["web-dev","java"]}]' ); $this->module->seeResponseIsJson(); - $this->module->seeResponseContainsJson(array('tags' => array('web-dev', 'java'))); - $this->module->seeResponseContainsJson(array('user' => 'John Doe', 'age' => 27)); + $this->module->seeResponseContainsJson(['tags' => ['web-dev', 'java']]); + $this->module->seeResponseContainsJson(['user' => 'John Doe', 'age' => 27]); } public function testArrayJson() @@ -124,7 +126,7 @@ public function testArrayJson() $this->setStubResponse( '[{"id":1,"title": "Bug should be fixed"},{"title": "Feature should be implemented","id":2}]' ); - $this->module->seeResponseContainsJson(array('id' => 1)); + $this->module->seeResponseContainsJson(['id' => 1]); } /** @@ -134,7 +136,7 @@ public function testSeeResponseContainsJsonFailsGracefullyWhenJsonResultIsNotArr { $this->shouldFail(); $this->setStubResponse(json_encode('no_status', JSON_THROW_ON_ERROR)); - $this->module->seeResponseContainsJson(array('id' => 1)); + $this->module->seeResponseContainsJson(['id' => 1]); } public function testDontSeeResponseJsonMatchesJsonPathPassesWhenJsonResultIsNotArray() @@ -147,16 +149,16 @@ public function testDontSeeInJson() { $this->setStubResponse('{"ticket": {"title": "Bug should be fixed", "user": {"name": "Davert"}}}'); $this->module->seeResponseIsJson(); - $this->module->dontSeeResponseContainsJson(array('name' => 'Davet')); - $this->module->dontSeeResponseContainsJson(array('user' => array('name' => 'Davet'))); - $this->module->dontSeeResponseContainsJson(array('user' => array('title' => 'Bug should be fixed'))); + $this->module->dontSeeResponseContainsJson(['name' => 'Davet']); + $this->module->dontSeeResponseContainsJson(['user' => ['name' => 'Davet']]); + $this->module->dontSeeResponseContainsJson(['user' => ['title' => 'Bug should be fixed']]); } public function testApplicationJsonIncludesJsonAsContent() { $this->module->haveHttpHeader('Content-Type', 'application/json'); - $this->module->sendPOST('/', array('name' => 'john')); - /** @var $request \Symfony\Component\BrowserKit\Request **/ + $this->module->sendPOST('/', ['name' => 'john']); + /** @var $request SymfonyRequest **/ $request = $this->module->client->getRequest(); $this->assertContains('application/json', $request->getServer()); $server = $request->getServer(); @@ -171,8 +173,8 @@ public function testApplicationJsonIncludesJsonAsContent() public function testApplicationJsonHeaderCheckIsCaseInsensitive() { $this->module->haveHttpHeader('content-type', 'application/json'); - $this->module->sendPOST('/', array('name' => 'john')); - /** @var $request \Symfony\Component\BrowserKit\Request **/ + $this->module->sendPOST('/', ['name' => 'john']); + /** @var $request SymfonyRequest **/ $request = $this->module->client->getRequest(); $server = $request->getServer(); $this->assertEquals('application/json', $server['HTTP_CONTENT_TYPE']); @@ -183,8 +185,8 @@ public function testApplicationJsonHeaderCheckIsCaseInsensitive() public function testGetApplicationJsonNotIncludesJsonAsContent() { $this->module->haveHttpHeader('Content-Type', 'application/json'); - $this->module->sendGET('/', array('name' => 'john')); - /** @var $request \Symfony\Component\BrowserKit\Request **/ + $this->module->sendGET('/', ['name' => 'john']); + /** @var $request SymfonyRequest **/ $request = $this->module->client->getRequest(); $this->assertNull($request->getContent()); $this->assertContains('john', $request->getParameters()); @@ -196,25 +198,26 @@ public function testGetApplicationJsonNotIncludesJsonAsContent() */ public function testTwoTests() { - $cest1 = Stub::makeEmpty('\Codeception\Test\Cest'); - $cest2 = Stub::makeEmpty('\Codeception\Test\Cest'); + $cest1 = Stub::makeEmpty(Cest::class); + $cest2 = Stub::makeEmpty(Cest::class); $this->module->sendGET('/rest/user/'); $this->module->seeResponseIsJson(); $this->module->seeResponseContains('davert'); - $this->module->seeResponseContainsJson(array('name' => 'davert')); + $this->module->seeResponseContainsJson(['name' => 'davert']); $this->module->seeResponseCodeIs(200); $this->module->dontSeeResponseCodeIs(404); - + $this->phpBrowser->_after($cest1); $this->module->_after($cest1); $this->module->_before($cest2); + $this->phpBrowser->_before($cest2); - + $this->module->sendGET('/rest/user/'); $this->module->seeResponseIsJson(); $this->module->seeResponseContains('davert'); - $this->module->seeResponseContainsJson(array('name' => 'davert')); + $this->module->seeResponseContainsJson(['name' => 'davert']); $this->module->seeResponseCodeIs(200); $this->module->dontSeeResponseCodeIs(404); } @@ -297,7 +300,7 @@ public function testSessionHeaderBackup() protected function shouldFail() { - $this->expectException('PHPUnit\Framework\AssertionFailedError'); + $this->expectException(AssertionFailedError::class); } public function testGrabFromCurrentUrl() diff --git a/tests/unit/Codeception/Module/PhpBrowserTest.php b/tests/unit/Codeception/Module/PhpBrowserTest.php index 8e81325..c9127c7 100644 --- a/tests/unit/Codeception/Module/PhpBrowserTest.php +++ b/tests/unit/Codeception/Module/PhpBrowserTest.php @@ -2,34 +2,41 @@ declare(strict_types=1); +use Codeception\Configuration as CodeceptConfig; +use Codeception\Exception\ElementNotFound; +use Codeception\Exception\ModuleException; use Codeception\Exception\TestRuntimeException; +use Codeception\Lib\Connector\Guzzle; +use Codeception\Lib\ModuleContainer; +use Codeception\Module\PhpBrowser; use Codeception\Stub; require_once 'tests/data/app/data.php'; require_once __DIR__ . '/TestsForBrowsers.php'; +use Codeception\Test\Cept; +use GuzzleHttp\Client as GuzzleClient; use GuzzleHttp\Handler\MockHandler; +use GuzzleHttp\HandlerStack as GuzzleHandlerStack; +use GuzzleHttp\Middleware as GuzzleMiddleware; use GuzzleHttp\Psr7\Response; -use PHPUnit\Framework\AssertionFailedError; +use Symfony\Component\BrowserKit\Cookie; final class PhpBrowserTest extends TestsForBrowsers { - /** - * @var \Codeception\Module\PhpBrowser - */ - protected $module; + protected PhpBrowser $module; - protected $history = []; + protected array $history = []; protected function _setUp() { - $container = Stub::make('Codeception\Lib\ModuleContainer'); - $this->module = new \Codeception\Module\PhpBrowser($container); + $container = Stub::make(ModuleContainer::class); + $this->module = new PhpBrowser($container); $url = 'http://localhost:8000'; $this->module->_setConfig(['url' => $url]); $this->module->_initialize(); $this->module->_before($this->makeTest()); - $this->module->guzzle->getConfig('handler')->push(\GuzzleHttp\Middleware::history($this->history)); + $this->module->guzzle->getConfig('handler')->push(GuzzleMiddleware::history($this->history)); } @@ -47,12 +54,16 @@ protected function _tearDown() if ($this->module) { $this->module->_after($this->makeTest()); } + data::clean(); } + /** + * @return \\Codeception\Test\Cept&\PHPUnit\Framework\MockObject\MockObject + */ protected function makeTest() { - return Stub::makeEmpty('\Codeception\Test\Cept'); + return Stub::makeEmpty(Cept::class); } public function testAjax() @@ -61,7 +72,7 @@ public function testAjax() $this->module->sendAjaxGetRequest('/info'); $this->assertNotNull(data::get('ajax')); - $this->module->sendAjaxPostRequest('/form/complex', array('show' => 'author')); + $this->module->sendAjaxPostRequest('/form/complex', ['show' => 'author']); $this->assertNotNull(data::get('ajax')); $post = data::get('form'); $this->assertEquals('author', $post['show']); @@ -79,8 +90,8 @@ public function testHtmlSnapshot() $this->module->amOnPage('/'); $testName="debugPhpBrowser"; $this->module->makeHtmlSnapshot($testName); - $this->assertFileExists(\Codeception\Configuration::outputDir().'debug/'.$testName.'.html'); - @unlink(\Codeception\Configuration::outputDir().'debug/'.$testName.'.html'); + $this->assertFileExists(CodeceptConfig::outputDir().'debug/'.$testName.'.html'); + @unlink(CodeceptConfig::outputDir().'debug/'.$testName.'.html'); } /** @@ -146,7 +157,7 @@ public function testSubmitFormGet() { $I = $this->module; $I->amOnPage('/search'); - $I->submitForm('form', array('searchQuery' => 'test')); + $I->submitForm('form', ['searchQuery' => 'test']); $I->see('Success'); } @@ -200,6 +211,7 @@ public function testRedirectWithGetParams() { $this->module->amOnPage('/redirect4'); $this->module->seeInCurrentUrl('/search?ln=test@gmail.com&sn=testnumber'); + $params = data::get('params'); $this->assertContains('test@gmail.com', $params); } @@ -265,11 +277,11 @@ public function testRedirectLimitReached() $this->module->client->setMaxRedirects(1); try { $this->module->amOnPage('/redirect_twice'); - $this->assertTrue(false, 'redirect limit is not respected'); - } catch (\LogicException $e) { + $this->fail('redirect limit is not respected'); + } catch (LogicException $exception) { $this->assertEquals( 'The maximum number (1) of redirections was reached.', - $e->getMessage(), + $exception->getMessage(), 'redirect limit is respected' ); } @@ -299,8 +311,9 @@ public function testRedirectToAnotherDomainUsingSchemalessUrl() new Response(200, [], 'Cool stuff') ]) ]); - /** @var \GuzzleHttp\HandlerStack $handlerStack */ + /** @var GuzzleHandlerStack $handlerStack */ $this->module->amOnUrl('http://fictional.redirector/redirect-to?url=//example.org/'); + $currentUrl = $this->module->client->getHistory()->current()->getUri(); $this->assertSame('http://example.org/', $currentUrl); } @@ -335,9 +348,9 @@ public function testSubmitFormWithQueries() { $this->module->amOnPage('/form/example3'); $this->module->seeElement('form'); - $this->module->submitForm('form', array( + $this->module->submitForm('form', [ 'name' => 'jon', - )); + ]); $form = data::get('form'); $this->assertEquals('jon', $form['name']); $this->module->seeCurrentUrlEquals('/form/example3?validate=yes'); @@ -368,13 +381,14 @@ public function testDeleteHeadersByEmptyValue() public function testCurlOptions() { - $this->module->_setConfig(array('url' => 'http://google.com', 'curl' => array('CURLOPT_NOBODY' => true))); + $this->module->_setConfig(['url' => 'http://google.com', 'curl' => ['CURLOPT_NOBODY' => true]]); $this->module->_initialize(); if (method_exists($this->module->guzzle, 'getConfig')) { $config = $this->module->guzzle->getConfig(); } else { $config = $this->module->guzzle->getDefaultOption('config'); } + $this->assertArrayHasKey('curl', $config); $this->assertArrayHasKey(CURLOPT_NOBODY, $config['curl']); } @@ -382,13 +396,14 @@ public function testCurlOptions() public function testCurlSslOptions() { - $this->module->_setConfig(array( + $this->module->_setConfig([ 'url' => 'https://github.com', - 'curl' => array( + 'curl' => [ 'CURLOPT_NOBODY' => true, 'CURLOPT_SSL_CIPHER_LIST' => 'TLSv1', - ))); + ]]); $this->module->_initialize(); + $config = $this->module->guzzle->getConfig(); $this->assertArrayHasKey('curl', $config); @@ -417,7 +432,7 @@ public function testHttpAuth() public function testRawGuzzle() { - $code = $this->module->executeInGuzzle(function (\GuzzleHttp\Client $client) { + $code = $this->module->executeInGuzzle(function (GuzzleClient $client): int { $res = $client->get('/info'); return $res->getStatusCode(); }); @@ -457,7 +472,8 @@ public function testDoubleSlash() { $I = $this->module; $I->amOnPage('/register'); - $I->submitForm('form', array('test' => 'test')); + $I->submitForm('form', ['test' => 'test']); + $formUrl = $this->module->client->getHistory()->current()->getUri(); $formPath = parse_url($formUrl)['path']; $this->assertEquals($formPath, '/register'); @@ -465,7 +481,7 @@ public function testDoubleSlash() public function testFillFieldWithoutPage() { - $this->expectException("\\Codeception\\Exception\\ModuleException"); + $this->expectException(ModuleException::class); $this->module->fillField('#name', 'Nothing special'); } @@ -493,12 +509,13 @@ public function testCookiesForDomain() $mock = new MockHandler([ new Response(200, ['X-Foo' => 'Bar']), ]); - $handler = \GuzzleHttp\HandlerStack::create($mock); - $handler->push(\GuzzleHttp\Middleware::history($this->history)); - $client = new \GuzzleHttp\Client(['handler' => $handler, 'base_uri' => 'http://codeception.com']); - $guzzleConnector = new \Codeception\Lib\Connector\Guzzle(); + $handler = GuzzleHandlerStack::create($mock); + $handler->push(GuzzleMiddleware::history($this->history)); + + $client = new GuzzleClient(['handler' => $handler, 'base_uri' => 'http://codeception.com']); + $guzzleConnector = new Guzzle(); $guzzleConnector->setClient($client); - $guzzleConnector->getCookieJar()->set(new \Symfony\Component\BrowserKit\Cookie('hello', 'world')); + $guzzleConnector->getCookieJar()->set(new Cookie('hello', 'world')); $guzzleConnector->request('GET', 'http://codeception.com/'); $this->assertArrayHasKey('cookies', $this->history[0]['options']); /** @var $cookie GuzzleHttp\Cookie\SetCookie **/ @@ -528,6 +545,7 @@ public function testSetCookiesByOptions() $this->module->amOnPage('/cookies'); $this->module->seeCurrentUrlEquals('/info'); } + /** * @issue https://github.com/Codeception/Codeception/issues/2234 */ @@ -543,7 +561,7 @@ public function testEmptyValueOfCookie() public function testRequestApi() { - $this->expectException('Codeception\Exception\ModuleException'); + $this->expectException(ModuleException::class); $response = $this->module->_request('POST', '/form/try', ['user' => 'davert']); $data = data::get('form'); $this->assertEquals('davert', $data['user']); @@ -568,7 +586,7 @@ public function testLoadPageApi() public function testClickFailure() { $this->module->amOnPage('/info'); - $this->expectException('Codeception\Exception\ElementNotFound'); + $this->expectException(ElementNotFound::class); $this->expectExceptionMessage("'Sign In!' is invalid CSS and XPath selector and Link or Button element with 'name=Sign In!' was not found"); $this->module->click('Sign In!'); } @@ -630,6 +648,7 @@ public function testFillFieldInGetFormWithoutId() $this->module->selectOption('select_name', 'two'); $this->module->fillField('search_name', 'searchterm'); $this->module->click('Submit'); + $params = data::get('query'); $this->assertEquals('two', $params['select_name']); $this->assertEquals('searchterm', $params['search_name']); @@ -637,7 +656,7 @@ public function testFillFieldInGetFormWithoutId() public function testGrabPageSourceWhenNotOnPage() { - $this->expectException('\Codeception\Exception\ModuleException'); + $this->expectException(ModuleException::class); $this->expectExceptionMessage('Page not loaded. Use `$I->amOnPage` (or hidden API methods `_request` and `_loadPage`) to open it'); $this->module->grabPageSource(); } @@ -684,6 +703,7 @@ public function testSetUserAgentUsingConfig() $this->module->_initialize(); $this->module->amOnPage('/user-agent'); + $response = $this->module->grabPageSource(); $this->assertEquals('Codeception User Agent Test 1.0', $response, 'Incorrect user agent'); } @@ -732,6 +752,7 @@ public function testSelectOptionByTextWhenItHasNoValue() $this->module->amOnPage('/form/bug5547'); $this->module->selectOption('#_payment_type', 'qwerty'); $this->module->click('Submit'); + $form = data::get('form'); $this->assertEquals('qwerty', $form['payment_type']); } diff --git a/tests/unit/Codeception/Module/TestsForBrowsers.php b/tests/unit/Codeception/Module/TestsForBrowsers.php index d0df175..ddf2c28 100644 --- a/tests/unit/Codeception/Module/TestsForBrowsers.php +++ b/tests/unit/Codeception/Module/TestsForBrowsers.php @@ -2,26 +2,26 @@ declare(strict_types=1); +use Codeception\Exception\ModuleException; + require_once 'TestsForWeb.php'; + /** * Author: davert * Date: 13.01.12 * - * Class TestsForMink - * Description: - * + * Class TestsForBrowsers */ - abstract class TestsForBrowsers extends TestsForWeb { public function testAmOnSubdomain() { - $this->module->_reconfigure(array('url' => 'http://google.com')); + $this->module->_reconfigure(['url' => 'http://google.com']); $this->module->amOnSubdomain('user'); $this->assertEquals('http://user.google.com', $this->module->_getUrl()); - $this->module->_reconfigure(array('url' => 'http://www.google.com')); + $this->module->_reconfigure(['url' => 'http://www.google.com']); $this->module->amOnSubdomain('user'); $this->assertEquals('http://user.google.com', $this->module->_getUrl()); } @@ -48,12 +48,12 @@ public function testHeadersRedirect() */ public function testSiteRootRelativePathsForBasePathWithSubdir() { - $this->module->_reconfigure(array('url' => 'http://localhost:8000/form')); + $this->module->_reconfigure(['url' => 'http://localhost:8000/form']); $this->module->amOnPage('/relative_siteroot'); $this->module->seeInCurrentUrl('/form/relative_siteroot'); - $this->module->submitForm('form', array( + $this->module->submitForm('form', [ 'test' => 'value' - )); + ]); $this->module->dontSeeInCurrentUrl('form/form/'); $this->module->amOnPage('relative_siteroot'); $this->module->click('Click me'); @@ -62,7 +62,7 @@ public function testSiteRootRelativePathsForBasePathWithSubdir() public function testOpenPageException() { - $this->expectException('Codeception\Exception\ModuleException'); + $this->expectException(ModuleException::class); $this->module->see('Hello'); } } diff --git a/tests/unit/Codeception/Module/TestsForWeb.php b/tests/unit/Codeception/Module/TestsForWeb.php index 057d135..9d571b5 100644 --- a/tests/unit/Codeception/Module/TestsForWeb.php +++ b/tests/unit/Codeception/Module/TestsForWeb.php @@ -2,21 +2,22 @@ declare(strict_types=1); +use Codeception\Exception\ElementNotFound; +use Codeception\Exception\MalformedLocatorException; +use Codeception\Module\PhpBrowser; +use Codeception\Step\Argument\PasswordArgument; +use Codeception\Test\Unit; +use PHPUnit\Framework\AssertionFailedError; + /** * Author: davert * Date: 13.01.12 * - * Class TestsForMink - * Description: - * + * Class TestsForWeb */ - -abstract class TestsForWeb extends \Codeception\Test\Unit +abstract class TestsForWeb extends Unit { - /** - * @var \Codeception\Module\PhpBrowser - */ - protected $module; + protected PhpBrowser $module; public function testAmOnPage() { @@ -95,7 +96,7 @@ public function testSeeIsCaseInsensitiveForUnicodeText() public function testDontSeeIsCaseInsensitiveForUnicodeText() { - $this->expectException("PHPUnit\Framework\AssertionFailedError"); + $this->expectException(AssertionFailedError::class); $this->module->amOnPage('/info'); $this->module->dontSee('ссылочка'); } @@ -132,7 +133,7 @@ public function testDontSeeLink() public function testSeeLinkFailsIfTextDoesNotMatch() { - $this->expectException('PHPUnit\Framework\AssertionFailedError'); + $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage("No links containing text 'Codeception' were found in page /external_url"); $this->module->amOnPage('/external_url'); $this->module->seeLink('Codeception'); @@ -140,7 +141,7 @@ public function testSeeLinkFailsIfTextDoesNotMatch() public function testSeeLinkFailsIfHrefDoesNotMatch() { - $this->expectException('PHPUnit\Framework\AssertionFailedError'); + $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage("No links containing text 'Next' and URL '/fsdfsdf/' were found in page /external_url"); $this->module->amOnPage('/external_url'); $this->module->seeLink('Next', '/fsdfsdf/'); @@ -148,7 +149,7 @@ public function testSeeLinkFailsIfHrefDoesNotMatch() public function testSeeLinkFailsIfHrefDoesNotMatchExactly() { - $this->expectException('PHPUnit\Framework\AssertionFailedError'); + $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage("No links containing text 'Next' and URL 'http://codeception' were found in page /external_url"); $this->module->amOnPage('/external_url'); $this->module->seeLink('Next', 'http://codeception'); @@ -156,7 +157,7 @@ public function testSeeLinkFailsIfHrefDoesNotMatchExactly() public function testDontSeeLinkFailsIfTextMatches() { - $this->expectException('PHPUnit\Framework\AssertionFailedError'); + $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage("Link containing text 'Next' was found in page /external_url"); $this->module->amOnPage('/external_url'); $this->module->dontSeeLink('Next'); @@ -164,7 +165,7 @@ public function testDontSeeLinkFailsIfTextMatches() public function testDontSeeLinkFailsIfTextAndUrlMatches() { - $this->expectException('PHPUnit\Framework\AssertionFailedError'); + $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage("Link containing text 'Next' and URL 'http://codeception.com/' was found in page /external_url"); $this->module->amOnPage('/external_url'); $this->module->dontSeeLink('Next', 'http://codeception.com/'); @@ -179,7 +180,7 @@ public function testSeeLinkMatchesRelativeLink() public function testDontSeeLinkMatchesRelativeLink() { - $this->expectException('PHPUnit\Framework\AssertionFailedError'); + $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage("Link containing text 'Sign in!' and URL '/login' was found in page /info"); $this->module->amOnPage('/info'); $this->module->dontSeeLink('Sign in!', '/login'); @@ -204,6 +205,7 @@ public function testClickByName() { $this->module->amOnPage('/form/button'); $this->module->click("btn0"); + $form = data::get('form'); $this->assertEquals('val', $form['text']); } @@ -231,6 +233,7 @@ public function testCheckboxByCss() $this->module->amOnPage('/form/checkbox'); $this->module->checkOption('#checkin'); $this->module->click('Submit'); + $form = data::get('form'); $this->assertEquals('agree', $form['terms']); } @@ -240,6 +243,7 @@ public function testCheckboxByName() $this->module->amOnPage('/form/checkbox'); $this->module->checkOption('terms'); $this->module->click('Submit'); + $form = data::get('form'); $this->assertEquals('agree', $form['terms']); } @@ -249,6 +253,7 @@ public function testCheckboxByLabel() $this->module->amOnPage('/form/checkbox'); $this->module->checkOption('I Agree'); $this->module->click('Submit'); + $form = data::get('form'); $this->assertEquals('agree', $form['terms']); } @@ -262,6 +267,7 @@ public function testCheckboxArray() $this->module->amOnPage('/form/checkbox_array'); $this->module->checkOption('#id2'); $this->module->click('Submit'); + $form = data::get('form'); $this->assertEquals('second', reset($form['field'])); } @@ -271,6 +277,7 @@ public function testSelectByCss() $this->module->amOnPage('/form/select'); $this->module->selectOption('form select[name=age]', 'adult'); $this->module->click('Submit'); + $form = data::get('form'); $this->assertEquals('adult', $form['age']); } @@ -280,6 +287,7 @@ public function testSelectByName() $this->module->amOnPage('/form/select'); $this->module->selectOption('age', 'adult'); $this->module->click('Submit'); + $form = data::get('form'); $this->assertEquals('adult', $form['age']); } @@ -289,6 +297,7 @@ public function testSelectByLabel() $this->module->amOnPage('/form/select'); $this->module->selectOption('Select your age', 'dead'); $this->module->click('Submit'); + $form = data::get('form'); $this->assertEquals('dead', $form['age']); } @@ -298,6 +307,7 @@ public function testSelectByLabelAndOptionText() $this->module->amOnPage('/form/select'); $this->module->selectOption('Select your age', '21-60'); $this->module->click('Submit'); + $form = data::get('form'); $this->assertEquals('adult', $form['age']); } @@ -324,6 +334,7 @@ public function testSeeSelectedOptionReturnsFirstOptionIfNotSelected() $this->module->amOnPage('/form/complex'); $this->module->seeOptionIsSelected('#age', 'below 13'); $this->module->click('Submit'); + $form = data::get('form'); $this->assertEquals('child', $form['age'], 'first option was not submitted'); } @@ -336,6 +347,7 @@ public function testSubmitSeveralSubmitsForm() { $this->module->amOnPage('/form/example8'); $this->module->click('form button[value="second"]'); + $form = data::get('form'); $this->assertEquals('second', $form['submit']); } @@ -350,6 +362,7 @@ public function testSubmitLotsOfSubmitsForm() { $this->module->amOnPage('/form/example11'); $this->module->click('form button[value="fifth"]'); + $form = data::get('form'); $this->assertEquals('fifth', $form['submit']); } @@ -357,25 +370,28 @@ public function testSubmitLotsOfSubmitsForm() public function testSelectMultipleOptionsByText() { $this->module->amOnPage('/form/select_multiple'); - $this->module->selectOption('What do you like the most?', array('Play Video Games', 'Have Sex')); + $this->module->selectOption('What do you like the most?', ['Play Video Games', 'Have Sex']); $this->module->click('Submit'); + $form = data::get('form'); - $this->assertEquals(array('play', 'adult'), $form['like']); + $this->assertEquals(['play', 'adult'], $form['like']); } public function testSelectMultipleOptionsByValue() { $this->module->amOnPage('/form/select_multiple'); - $this->module->selectOption('What do you like the most?', array('eat', 'adult')); + $this->module->selectOption('What do you like the most?', ['eat', 'adult']); $this->module->click('Submit'); + $form = data::get('form'); - $this->assertEquals(array('eat', 'adult'), $form['like']); + $this->assertEquals(['eat', 'adult'], $form['like']); } public function testHidden() { $this->module->amOnPage('/form/hidden'); $this->module->click('Submit'); + $form = data::get('form'); $this->assertEquals('kill_people', $form['action']); } @@ -385,6 +401,7 @@ public function testTextareaByCss() $this->module->amOnPage('/form/textarea'); $this->module->fillField('textarea', 'Nothing special'); $this->module->click('Submit'); + $form = data::get('form'); $this->assertEquals('Nothing special', $form['description']); } @@ -394,6 +411,7 @@ public function testTextareaByLabel() $this->module->amOnPage('/form/textarea'); $this->module->fillField('Description', 'Nothing special'); $this->module->click('Submit'); + $form = data::get('form'); $this->assertEquals('Nothing special', $form['description']); } @@ -403,6 +421,7 @@ public function testTextFieldByCss() $this->module->amOnPage('/form/field'); $this->module->fillField('#name', 'Nothing special'); $this->module->click('Submit'); + $form = data::get('form'); $this->assertEquals('Nothing special', $form['name']); } @@ -413,6 +432,7 @@ public function testTextFieldByName() $this->module->fillField('LoginForm[username]', 'davert'); $this->module->fillField('LoginForm[password]', '123456'); $this->module->click('Login'); + $login = data::get('form'); $this->assertEquals('davert', $login['LoginForm']['username']); $this->assertEquals('123456', $login['LoginForm']['password']); @@ -423,6 +443,7 @@ public function testTextFieldByLabel() $this->module->amOnPage('/form/field'); $this->module->fillField('Name', 'Nothing special'); $this->module->click('Submit'); + $form = data::get('form'); $this->assertEquals('Nothing special', $form['name']); } @@ -432,6 +453,7 @@ public function testTextFieldByLabelWithoutFor() $this->module->amOnPage('/form/field'); $this->module->fillField('Other label', 'Nothing special'); $this->module->click('Submit'); + $form = data::get('form'); $this->assertEquals('Nothing special', $form['othername']); } @@ -572,7 +594,7 @@ public function testSeeInFieldOnSelectMultiple() public function testSeeInFieldWithExactMatch() { $this->module->amOnPage('/form/field_values'); - $this->module->seeInField(array('name' => 'select2'), 'see test one'); + $this->module->seeInField(['name' => 'select2'], 'see test one'); } public function testDontSeeInFieldOnInput() @@ -615,7 +637,7 @@ public function testSeeInFormFields() public function testSeeInFormFieldsFails() { $this->module->amOnPage('/form/field_values'); - $this->expectException("PHPUnit\Framework\AssertionFailedError"); + $this->expectException(AssertionFailedError::class); $params = [ 'radio1' => 'something I should not see', 'checkbox1' => true, @@ -653,7 +675,7 @@ public function testDontSeeInFormFields() public function testDontSeeInFormFieldsFails() { $this->module->amOnPage('/form/field_values'); - $this->expectException("PHPUnit\Framework\AssertionFailedError"); + $this->expectException(AssertionFailedError::class); $params = [ 'checkbox[]' => [ 'wont see this anyway', @@ -730,6 +752,7 @@ public function testGrabValueFromWithFillField() { $this->module->amOnPage('/form/bug3866'); $this->module->fillField('empty', 'new value'); + $result = $this->module->grabValueFrom('#empty'); $this->assertEquals('new value', $result); $this->module->fillField('empty_textarea', 'new value'); @@ -781,7 +804,7 @@ public function testSeeElementOnPage() // regression test. https://github.com/Codeception/Codeception/issues/587 public function testSeeElementOnPageFails() { - $this->expectException("PHPUnit\Framework\AssertionFailedError"); + $this->expectException(AssertionFailedError::class); $this->module->amOnPage('/form/field'); $this->module->dontSeeElement('input[name=name]'); } @@ -795,7 +818,6 @@ public function testCookies() $this->module->setCookie($cookie_name, $cookie_value); $this->module->setCookie('notthatcookie', '22222'); - $this->module->seeCookie($cookie_name); $this->module->dontSeeCookie('evil_cookie'); @@ -946,6 +968,7 @@ public function testExample1() $this->module->fillField('#LoginForm_password', '123456'); $this->module->checkOption('#LoginForm_rememberMe'); $this->module->click('Login'); + $login = data::get('form'); $this->assertEquals('davert', $login['LoginForm']['username']); $this->assertEquals('123456', $login['LoginForm']['password']); @@ -958,6 +981,7 @@ public function testExample2() $this->module->fillField('input[name=username]', 'davert'); $this->module->fillField('input[name=password]', '123456'); $this->module->click('Log on'); + $login = data::get('form'); $this->assertEquals('davert', $login['username']); $this->assertEquals('123456', $login['password']); @@ -1039,10 +1063,10 @@ public function testExample9() public function testSubmitForm() { $this->module->amOnPage('/form/complex'); - $this->module->submitForm('form', array( + $this->module->submitForm('form', [ 'name' => 'Davert', 'description' => 'Is Codeception maintainer' - )); + ]); $form = data::get('form'); $this->assertEquals('Davert', $form['name']); $this->assertEquals('Is Codeception maintainer', $form['description']); @@ -1069,9 +1093,9 @@ public function testSubmitFormWithFillField() public function testSubmitFormWithoutButton() { $this->module->amOnPage('/form/empty'); - $this->module->submitForm('form', array( + $this->module->submitForm('form', [ 'text' => 'Hello!' - )); + ]); $form = data::get('form'); $this->assertEquals('Hello!', $form['text']); } @@ -1080,6 +1104,7 @@ public function testSubmitFormWithAmpersand() { $this->module->amOnPage('/form/submitform_ampersands'); $this->module->submitForm('form', []); + $form = data::get('form'); $this->assertEquals('this & that', $form['test']); } @@ -1088,6 +1113,7 @@ public function testSubmitFormWithArrayField() { $this->module->amOnPage('/form/example17'); $this->module->submitForm('form', []); + $data = data::get('form'); $this->assertSame('baz', $data['FooBar']['bar']); $this->assertArrayNotHasKey('FooBar[bar]', $data); @@ -1112,6 +1138,7 @@ public function testSubmitFormWithMultiSelect() { $this->module->amOnPage('/form/submitform_multiple'); $this->module->submitForm('form', []); + $form = data::get('form'); $this->assertCount(2, $form['select']); $this->assertEquals('see test one', $form['select'][0]); @@ -1164,6 +1191,7 @@ public function testSubmitFormWithDefaultTextareaValue() { $this->module->amOnPage('/form/textarea'); $this->module->submitForm('form', []); + $form = data::get('form'); $this->assertEquals('sunrise', $form['description']); } @@ -1186,6 +1214,7 @@ public function testSelectTwoSubmitsByText() $this->module->amOnPage('/form/select_two_submits'); $this->module->selectOption('What kind of sandwich would you like?', 2); $this->module->click('Save'); + $form = data::get('form'); $this->assertEquals(2, $form['sandwich_select']); } @@ -1195,13 +1224,14 @@ public function testSelectTwoSubmitsByCSS() $this->module->amOnPage('/form/select_two_submits'); $this->module->selectOption("form select[name='sandwich_select']", '2'); $this->module->click('Save'); + $form = data::get('form'); $this->assertEquals(2, $form['sandwich_select']); } protected function shouldFail() { - $this->expectException('PHPUnit\Framework\AssertionFailedError'); + $this->expectException(AssertionFailedError::class); } /** @@ -1212,6 +1242,7 @@ public function testSubmitFormWithTwoSubmitButtonsSubmitsCorrectValue() $this->module->amOnPage('/form/example10'); $this->module->seeElement("#button2"); $this->module->click("#button2"); + $form = data::get('form'); $this->assertArrayHasKey('button2', $form); $this->assertArrayHasKey('username', $form); @@ -1227,6 +1258,7 @@ public function testSubmitFormWithTwoSubmitButtonsSubmitsCorrectValueAfterFillFi $this->module->amOnPage('/form/example10'); $this->module->fillField("username", "bob"); $this->module->click("#button2"); + $form = data::get('form'); $this->assertArrayHasKey('button2', $form); $this->assertArrayHasKey('username', $form); @@ -1240,18 +1272,18 @@ public function testSubmitFormWithTwoSubmitButtonsSubmitsCorrectValueAfterFillFi public function testSubmitFormWithDocRelativePathForAction() { $this->module->amOnPage('/form/example12'); - $this->module->submitForm('form', array( + $this->module->submitForm('form', [ 'test' => 'value' - )); + ]); $this->module->seeCurrentUrlEquals('/form/example11'); } public function testSubmitFormWithDocRelativePathForActionFromDefaultPage() { $this->module->amOnPage('/form/'); - $this->module->submitForm('form', array( + $this->module->submitForm('form', [ 'test' => 'value' - )); + ]); $this->module->seeCurrentUrlEquals('/form/example11'); } @@ -1268,9 +1300,9 @@ public function testLinkWithDocRelativeURLFromDefaultPage() public function testSubmitFormWithDefaultRadioAndCheckboxValues() { $this->module->amOnPage('/form/example16'); - $this->module->submitForm('form', array( + $this->module->submitForm('form', [ 'test' => 'value' - )); + ]); $form = data::get('form'); $this->assertArrayHasKey('checkbox1', $form, 'Checkbox value not sent'); $this->assertArrayHasKey('radio1', $form, 'Radio button value not sent'); @@ -1281,17 +1313,17 @@ public function testSubmitFormWithDefaultRadioAndCheckboxValues() public function testSubmitFormCheckboxWithBoolean() { $this->module->amOnPage('/form/example16'); - $this->module->submitForm('form', array( + $this->module->submitForm('form', [ 'checkbox1' => true - )); + ]); $form = data::get('form'); $this->assertArrayHasKey('checkbox1', $form, 'Checkbox value not sent'); $this->assertEquals('testing', $form['checkbox1']); $this->module->amOnPage('/form/example16'); - $this->module->submitForm('form', array( + $this->module->submitForm('form', [ 'checkbox1' => false - )); + ]); $form = data::get('form'); $this->assertArrayNotHasKey('checkbox1', $form, 'Checkbox value sent'); } @@ -1306,9 +1338,9 @@ public function testSubmitFormWithCheckboxesWithoutValue() public function testSubmitFormWithButtons() { $this->module->amOnPage('/form/form_with_buttons'); - $this->module->submitForm('form', array( + $this->module->submitForm('form', [ 'test' => 'value', - )); + ]); $form = data::get('form'); $this->assertFalse( isset($form['button1']) || isset($form['button2']) || isset($form['button3']) || isset($form['button4']), @@ -1316,9 +1348,9 @@ public function testSubmitFormWithButtons() ); $this->module->amOnPage('/form/form_with_buttons'); - $this->module->submitForm('form', array( + $this->module->submitForm('form', [ 'test' => 'value', - ), 'button3'); + ], 'button3'); $form = data::get('form'); $this->assertFalse( isset($form['button1']) || isset($form['button2']) || isset($form['button4']), @@ -1328,9 +1360,9 @@ public function testSubmitFormWithButtons() $this->assertEquals($form['button3'], 'third', 'Button value for button3 should equal third'); $this->module->amOnPage('/form/form_with_buttons'); - $this->module->submitForm('form', array( + $this->module->submitForm('form', [ 'test' => 'value', - ), 'button4'); + ], 'button4'); $form = data::get('form'); $this->assertFalse( isset($form['button1']) || isset($form['button2']) || isset($form['button3']), @@ -1345,28 +1377,28 @@ public function testSubmitFormWithButtons() */ public function testWrongXpath() { - $this->expectException('Codeception\Exception\MalformedLocatorException'); + $this->expectException(MalformedLocatorException::class); $this->module->amOnPage('/'); $this->module->seeElement('//aas[asd}[sd]a[/['); } public function testWrongCSS() { - $this->expectException('Codeception\Exception\MalformedLocatorException'); + $this->expectException(MalformedLocatorException::class); $this->module->amOnPage('/'); $this->module->seeElement('.user#iasosexpectException('Codeception\Exception\MalformedLocatorException'); + $this->expectException(MalformedLocatorException::class); $this->module->amOnPage('/'); $this->module->seeElement(['css' => 'hel!1$expectException('Codeception\Exception\MalformedLocatorException'); + $this->expectException(MalformedLocatorException::class); $this->module->amOnPage('/'); $this->module->seeElement(['xpath' => 'hellorld']); } @@ -1406,6 +1438,7 @@ public function testTextFieldByNameFirstNotCss() $this->module->fillField('description', 'description'); $this->module->fillField('price', '19.99'); $this->module->click('Create'); + $data = data::get('form'); $this->assertEquals('Special Widget', $data['title']); } @@ -1418,6 +1451,7 @@ public function testCheckingOptionsWithComplexNames() $this->module->amOnPage('/form/bug1535'); $this->module->checkOption('#bmessage-topicslinks input[value="4"]'); $this->module->click('Submit'); + $data = data::get('form'); $this->assertContains('4', $data['BMessage']['topicsLinks']); } @@ -1434,6 +1468,7 @@ public function testUnreachableField() $this->module->fillField('input[name="users[]"]', 'davert'); $this->module->attachFile('input[name="files[]"]', 'app/avatar.jpg'); $this->module->click('Submit'); + $data = data::get('form'); $this->assertContains('test3', $data['items'][1]); $this->assertContains('test2', $data['captions']); @@ -1444,6 +1479,7 @@ public function testSubmitAdjacentForms() { $this->module->amOnPage('/form/submit_adjacentforms'); $this->module->submitForm('#form-2', []); + $data = data::get('form'); $this->assertArrayHasKey('second-field', $data); $this->assertArrayNotHasKey('first-field', $data); @@ -1456,6 +1492,7 @@ public function testSubmitAdjacentFormsByButton() $this->module->fillField('first-field', 'First'); $this->module->fillField('second-field', 'Second'); $this->module->click('#submit1'); + $data = data::get('form'); $this->assertArrayHasKey('first-field', $data); $this->assertArrayNotHasKey('second-field', $data); @@ -1465,6 +1502,7 @@ public function testSubmitAdjacentFormsByButton() $this->module->fillField('first-field', 'First'); $this->module->fillField('second-field', 'Second'); $this->module->click('#submit2'); + $data = data::get('form'); $this->assertArrayNotHasKey('first-field', $data); $this->assertArrayHasKey('second-field', $data); @@ -1499,12 +1537,12 @@ public function testSelectAndCheckOptionSquareBracketNames() $this->module->selectOption('//input[@name="input_radio_name"]', '1'); $this->module->selectOption('//input[@name="input_radio_name"]', '2'); - $this->module->checkOption('//input[@name="input_checkbox_name"]', '1'); - $this->module->checkOption('//input[@name="input_checkbox_name"]', '2'); + $this->module->checkOption('//input[@name="input_checkbox_name"]'); + $this->module->checkOption('//input[@name="input_checkbox_name"]'); - $this->module->checkOption('//input[@name="input[checkbox][name][]"]', '1'); - $this->module->checkOption('//input[@name="input[checkbox][name][]"]', '2'); - $this->module->checkOption('//input[@name="input[checkbox][name][]"]', '1'); + $this->module->checkOption('//input[@name="input[checkbox][name][]"]'); + $this->module->checkOption('//input[@name="input[checkbox][name][]"]'); + $this->module->checkOption('//input[@name="input[checkbox][name][]"]'); $this->module->selectOption('//select[@name="select_name"]', '1'); @@ -1520,6 +1558,7 @@ public function testFillFieldWithAmpersand() $this->module->amOnPage('/form/field'); $this->module->fillField('Name', 'this & that'); $this->module->click('Submit'); + $form = data::get('form'); $this->assertEquals('this & that', $form['name']); } @@ -1576,7 +1615,7 @@ public function testClickMultiByteLink() */ public function testClickThrowsElementNotFoundExceptionWhenTextContainsNumber() { - $this->expectException('Codeception\Exception\ElementNotFound'); + $this->expectException(ElementNotFound::class); $this->expectExceptionMessage("'Link 2' is invalid CSS and XPath selector and Link or Button element with 'name=Link 2' was not found."); $this->module->amOnPage('/info'); $this->module->click('Link 2'); @@ -1594,6 +1633,7 @@ public function testSelectOptionValueSelector() $this->module->amOnPage('/form/select_selectors'); $this->module->selectOption('age', ['value' => '20']); $this->module->click('Submit'); + $data = data::get('form'); $this->assertEquals('20', $data['age']); } @@ -1698,7 +1738,7 @@ public function testAttachFileThrowsCorrectMessageWhenFileDoesNotExist() { $filename = 'does-not-exist.jpg'; $expectedMessage = 'File does not exist: ' . codecept_data_dir($filename); - $this->expectException('InvalidArgumentException'); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage($expectedMessage); $this->module->amOnPage('/form/file'); @@ -1708,8 +1748,9 @@ public function testAttachFileThrowsCorrectMessageWhenFileDoesNotExist() public function testPasswordArgument() { $this->module->amOnPage('/form/password_argument'); - $this->module->fillField('password', new \Codeception\Step\Argument\PasswordArgument('thisissecret')); + $this->module->fillField('password', new PasswordArgument('thisissecret')); $this->module->click('Submit'); + $data = data::get('form'); $this->assertEquals('thisissecret', $data['password']); } From e9afe978c934df2bf51cf90743a06b2aeac91a30 Mon Sep 17 00:00:00 2001 From: TavoNiievez Date: Sat, 4 Dec 2021 08:54:33 -0500 Subject: [PATCH 10/26] Require Codeception 4 again --- composer.json | 82 +++++++++++++-------------- src/Codeception/Module/PhpBrowser.php | 8 +-- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/composer.json b/composer.json index 629a0f0..70eb7b9 100644 --- a/composer.json +++ b/composer.json @@ -1,43 +1,43 @@ { - "name": "codeception/module-phpbrowser", - "description": "Codeception module for testing web application over HTTP", - "keywords": [ "codeception", "http", "functional-testing" ], - "homepage": "https://codeception.com/", - "type": "library", - "license": "MIT", - "authors": [ - { - "name": "Michael Bodnarchuk" - }, - { - "name": "Gintautas Miselis" - } - ], - "minimum-stability": "RC", - "require": { - "php": "^7.4 || ^8.0", - "ext-json": "*", - "guzzlehttp/guzzle": "^7.3", - "codeception/lib-innerbrowser": "^1.5 || *@dev", - "codeception/codeception": "^5.0 || *@dev" - }, - "require-dev": { - "ext-curl": "*", - "aws/aws-sdk-php": "^3.199", - "codeception/module-rest": "^1.3 || *@dev" - }, - "conflict": { - "codeception/codeception": "<5.0" - }, - "suggest": { - "codeception/phpbuiltinserver": "Start and stop PHP built-in web server for your tests" - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "config": { - "classmap-authoritative": true - } + "name": "codeception/module-phpbrowser", + "description": "Codeception module for testing web application over HTTP", + "keywords": [ "codeception", "http", "functional-testing" ], + "homepage": "https://codeception.com/", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Michael Bodnarchuk" + }, + { + "name": "Gintautas Miselis" + } + ], + "minimum-stability": "RC", + "require": { + "php": "^7.4 | ^8.0", + "ext-json": "*", + "guzzlehttp/guzzle": "^7.3", + "codeception/lib-innerbrowser": "^1.5 | *@dev", + "codeception/codeception": "^4.0 | *@dev" + }, + "require-dev": { + "ext-curl": "*", + "aws/aws-sdk-php": "^3.199", + "codeception/module-rest": "^1.3 | *@dev" + }, + "conflict": { + "codeception/codeception": "<4.0" + }, + "suggest": { + "codeception/phpbuiltinserver": "Start and stop PHP built-in web server for your tests" + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "config": { + "classmap-authoritative": true + } } diff --git a/src/Codeception/Module/PhpBrowser.php b/src/Codeception/Module/PhpBrowser.php index 98ca7d0..580e1df 100644 --- a/src/Codeception/Module/PhpBrowser.php +++ b/src/Codeception/Module/PhpBrowser.php @@ -221,7 +221,7 @@ public function _getResponseCode() return $this->getResponseStatusCode(); } - public function _initializeSession(): void + public function _initializeSession() { // independent sessions need independent cookies $this->client = new Guzzle(); @@ -258,7 +258,7 @@ public function _prepareSession(): void $this->client->setClient($this->guzzle); } - public function _backupSession(): array + public function _backupSession() { return [ 'client' => $this->client, @@ -268,14 +268,14 @@ public function _backupSession(): array ]; } - public function _loadSession($session): void + public function _loadSession($session) { foreach ($session as $key => $val) { $this->$key = $val; } } - public function _closeSession($session = null): void + public function _closeSession($session = null) { unset($session); } From 955440661c41985962f5b7f68ab5b532d966768c Mon Sep 17 00:00:00 2001 From: TavoNiievez Date: Sun, 5 Dec 2021 00:26:34 -0500 Subject: [PATCH 11/26] Fix CI --- src/Codeception/Module/PhpBrowser.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Codeception/Module/PhpBrowser.php b/src/Codeception/Module/PhpBrowser.php index 580e1df..edc99b6 100644 --- a/src/Codeception/Module/PhpBrowser.php +++ b/src/Codeception/Module/PhpBrowser.php @@ -12,6 +12,7 @@ use Codeception\TestInterface; use Codeception\Util\Uri; use GuzzleHttp\Client as GuzzleClient; +use Symfony\Component\BrowserKit\AbstractBrowser; /** * Uses [Guzzle](https://docs.guzzlephp.org/en/stable/) to interact with your application over CURL. @@ -123,7 +124,7 @@ class PhpBrowser extends InnerBrowser implements Remote, MultiSession /** * @var Guzzle */ - public $client; + public ?AbstractBrowser $client = null; public ?GuzzleClient $guzzle = null; From d66924f343032a480fde1264b606c3357d2ed0d2 Mon Sep 17 00:00:00 2001 From: Gustavo Nieves <64917965+TavoNiievez@users.noreply.github.com> Date: Sat, 18 Dec 2021 09:13:57 -0500 Subject: [PATCH 12/26] Update dependencies (#20) Co-authored-by: Gintautas Miselis --- composer.json | 10 +++++----- src/Codeception/Lib/Connector/Guzzle.php | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index 70eb7b9..54ac7f8 100644 --- a/composer.json +++ b/composer.json @@ -17,17 +17,17 @@ "require": { "php": "^7.4 | ^8.0", "ext-json": "*", - "guzzlehttp/guzzle": "^7.3", - "codeception/lib-innerbrowser": "^1.5 | *@dev", - "codeception/codeception": "^4.0 | *@dev" + "guzzlehttp/guzzle": "^7.4", + "codeception/lib-innerbrowser": "^2.0 | *@dev", + "codeception/codeception": "^4.1 | *@dev" }, "require-dev": { "ext-curl": "*", "aws/aws-sdk-php": "^3.199", - "codeception/module-rest": "^1.3 | *@dev" + "codeception/module-rest": "^2.0 | *@dev" }, "conflict": { - "codeception/codeception": "<4.0" + "codeception/codeception": "<4.1" }, "suggest": { "codeception/phpbuiltinserver": "Start and stop PHP built-in web server for your tests" diff --git a/src/Codeception/Lib/Connector/Guzzle.php b/src/Codeception/Lib/Connector/Guzzle.php index 302f819..6d2415b 100644 --- a/src/Codeception/Lib/Connector/Guzzle.php +++ b/src/Codeception/Lib/Connector/Guzzle.php @@ -171,7 +171,7 @@ protected function getAbsoluteUri($uri) // relative url if (!$this->getHistory()->isEmpty()) { - return Uri::mergeUrls((string)$this->getHistory()->current()->getUri(), $uri); + return Uri::mergeUrls($this->getHistory()->current()->getUri(), $uri); } } From fda6d97253d0595843adb87ec0b9b7d6d89539ac Mon Sep 17 00:00:00 2001 From: Gustavo Nieves <64917965+TavoNiievez@users.noreply.github.com> Date: Tue, 21 Dec 2021 10:16:28 -0500 Subject: [PATCH 13/26] Fix some types (#21) --- src/Codeception/Lib/Connector/Guzzle.php | 2 +- tests/unit/Codeception/Module/TestsForWeb.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Codeception/Lib/Connector/Guzzle.php b/src/Codeception/Lib/Connector/Guzzle.php index 6d2415b..3816b1d 100644 --- a/src/Codeception/Lib/Connector/Guzzle.php +++ b/src/Codeception/Lib/Connector/Guzzle.php @@ -156,7 +156,7 @@ protected function createResponse(Psr7Response $psr7Response): BrowserKitRespons return new BrowserKitResponse($body, $status, $headers); } - protected function getAbsoluteUri($uri) + protected function getAbsoluteUri(string $uri): string { $baseUri = $this->client->getConfig('base_uri'); if (strpos($uri, '://') === false && strpos($uri, '//') !== 0) { diff --git a/tests/unit/Codeception/Module/TestsForWeb.php b/tests/unit/Codeception/Module/TestsForWeb.php index 9d571b5..f4c817d 100644 --- a/tests/unit/Codeception/Module/TestsForWeb.php +++ b/tests/unit/Codeception/Module/TestsForWeb.php @@ -1212,7 +1212,7 @@ public function testClickLinkWithInnerSpan() public function testSelectTwoSubmitsByText() { $this->module->amOnPage('/form/select_two_submits'); - $this->module->selectOption('What kind of sandwich would you like?', 2); + $this->module->selectOption('What kind of sandwich would you like?', '2'); $this->module->click('Save'); $form = data::get('form'); From 856a4aa8c4b0727d8343378cd3a09c0d977d5536 Mon Sep 17 00:00:00 2001 From: Gustavo Nieves <64917965+TavoNiievez@users.noreply.github.com> Date: Sat, 5 Feb 2022 14:20:27 -0500 Subject: [PATCH 14/26] Support for Codeception 5 (#25) Co-authored-by: Dan Barrett --- .github/workflows/main.yml | 2 +- composer.json | 8 ++++---- src/Codeception/Module/PhpBrowser.php | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c563b02..f3b7f28 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: - php: [7.4, 8.0] + php: [8.0, 8.1] steps: - name: Checkout code diff --git a/composer.json b/composer.json index 54ac7f8..b0c3292 100644 --- a/composer.json +++ b/composer.json @@ -13,13 +13,13 @@ "name": "Gintautas Miselis" } ], - "minimum-stability": "RC", + "minimum-stability": "dev", "require": { - "php": "^7.4 | ^8.0", + "php": "^8.0", "ext-json": "*", "guzzlehttp/guzzle": "^7.4", "codeception/lib-innerbrowser": "^2.0 | *@dev", - "codeception/codeception": "^4.1 | *@dev" + "codeception/codeception": "^5.0.0-alpha1" }, "require-dev": { "ext-curl": "*", @@ -27,7 +27,7 @@ "codeception/module-rest": "^2.0 | *@dev" }, "conflict": { - "codeception/codeception": "<4.1" + "codeception/codeception": "<5.0" }, "suggest": { "codeception/phpbuiltinserver": "Start and stop PHP built-in web server for your tests" diff --git a/src/Codeception/Module/PhpBrowser.php b/src/Codeception/Module/PhpBrowser.php index edc99b6..672e4c1 100644 --- a/src/Codeception/Module/PhpBrowser.php +++ b/src/Codeception/Module/PhpBrowser.php @@ -222,7 +222,7 @@ public function _getResponseCode() return $this->getResponseStatusCode(); } - public function _initializeSession() + public function _initializeSession(): void { // independent sessions need independent cookies $this->client = new Guzzle(); @@ -259,7 +259,7 @@ public function _prepareSession(): void $this->client->setClient($this->guzzle); } - public function _backupSession() + public function _backupSession(): array { return [ 'client' => $this->client, @@ -269,14 +269,14 @@ public function _backupSession() ]; } - public function _loadSession($session) + public function _loadSession($session): void { foreach ($session as $key => $val) { $this->$key = $val; } } - public function _closeSession($session = null) + public function _closeSession($session = null): void { unset($session); } From 3deb8777356d83d834ebc1c835602f8bcc3829aa Mon Sep 17 00:00:00 2001 From: Dan Barrett Date: Sat, 12 Feb 2022 12:45:16 +1100 Subject: [PATCH 15/26] Removed redundant line in .gitattributes file --- .gitattributes | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 87f3679..2d44cfe 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,6 +2,5 @@ /tests export-ignore /.gitattributes export-ignore /.gitignore export-ignore -/Robofile.php export-ignore /*.md export-ignore /*.yml export-ignore From 17f39b31830e94187546f950a114ac8ba6b3f76b Mon Sep 17 00:00:00 2001 From: Dan Barrett Date: Sat, 12 Feb 2022 12:49:00 +1100 Subject: [PATCH 16/26] Improved support for Codeception 5/PHP 8 --- readme.md | 2 +- src/Codeception/Module/PhpBrowser.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 144cbb8..3c26e32 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,7 @@ A Codeception module for testing web application over HTTP. ## Requirements -* `PHP 7.4` or higher. +* `PHP 8.0` or higher. ## Installation diff --git a/src/Codeception/Module/PhpBrowser.php b/src/Codeception/Module/PhpBrowser.php index 672e4c1..0222876 100644 --- a/src/Codeception/Module/PhpBrowser.php +++ b/src/Codeception/Module/PhpBrowser.php @@ -83,12 +83,12 @@ class PhpBrowser extends InnerBrowser implements Remote, MultiSession /** * @var string[] */ - protected $requiredFields = ['url']; + protected array $requiredFields = ['url']; /** - * @var array + * @var array */ - protected $config = [ + protected array $config = [ 'headers' => [], 'verify' => false, 'expect' => false, From f6fdca344b33c6ac2e2abede158856a3bd24f7d3 Mon Sep 17 00:00:00 2001 From: Dan Barrett Date: Sat, 12 Feb 2022 12:49:28 +1100 Subject: [PATCH 17/26] Normalise and cleanup of composer.json --- composer.json | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index b0c3292..856fb98 100644 --- a/composer.json +++ b/composer.json @@ -1,10 +1,13 @@ { "name": "codeception/module-phpbrowser", "description": "Codeception module for testing web application over HTTP", - "keywords": [ "codeception", "http", "functional-testing" ], - "homepage": "https://codeception.com/", - "type": "library", "license": "MIT", + "type": "library", + "keywords": [ + "codeception", + "http", + "functional-testing" + ], "authors": [ { "name": "Michael Bodnarchuk" @@ -13,18 +16,18 @@ "name": "Gintautas Miselis" } ], - "minimum-stability": "dev", + "homepage": "https://codeception.com/", "require": { "php": "^8.0", "ext-json": "*", - "guzzlehttp/guzzle": "^7.4", - "codeception/lib-innerbrowser": "^2.0 | *@dev", - "codeception/codeception": "^5.0.0-alpha1" + "codeception/codeception": "dev-5.0-interfaces as 5.0.0", + "codeception/lib-innerbrowser": "^2.0 || *@dev", + "guzzlehttp/guzzle": "^7.4" }, "require-dev": { "ext-curl": "*", "aws/aws-sdk-php": "^3.199", - "codeception/module-rest": "^2.0 | *@dev" + "codeception/module-rest": "^2.0 || *@dev" }, "conflict": { "codeception/codeception": "<5.0" @@ -32,12 +35,14 @@ "suggest": { "codeception/phpbuiltinserver": "Start and stop PHP built-in web server for your tests" }, + "minimum-stability": "dev", "autoload": { "classmap": [ "src/" ] }, "config": { - "classmap-authoritative": true + "classmap-authoritative": true, + "sort-packages": true } } From 04570537cf8e9296882daa70d2b8c9a0dee5b47e Mon Sep 17 00:00:00 2001 From: Dan Barrett Date: Sat, 12 Feb 2022 14:09:36 +1100 Subject: [PATCH 18/26] Update minimum requirement for `lib-innerbrowser` --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 856fb98..bbd2981 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "php": "^8.0", "ext-json": "*", "codeception/codeception": "dev-5.0-interfaces as 5.0.0", - "codeception/lib-innerbrowser": "^2.0 || *@dev", + "codeception/lib-innerbrowser": "^3.0", "guzzlehttp/guzzle": "^7.4" }, "require-dev": { From a3f9d3ad89acb877e2295d2d44353e0214957239 Mon Sep 17 00:00:00 2001 From: Gintautas Miselis Date: Wed, 16 Feb 2022 11:53:30 +0200 Subject: [PATCH 19/26] Fix codeception/codeception constraint --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index bbd2981..a2a2661 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,7 @@ "require": { "php": "^8.0", "ext-json": "*", - "codeception/codeception": "dev-5.0-interfaces as 5.0.0", + "codeception/codeception": "*@dev", "codeception/lib-innerbrowser": "^3.0", "guzzlehttp/guzzle": "^7.4" }, From c38af20260a4ceee6a6a4ce81909861e0d876442 Mon Sep 17 00:00:00 2001 From: Gintautas Miselis Date: Wed, 16 Feb 2022 12:12:05 +0200 Subject: [PATCH 20/26] Fix lib-innerbrowser version constraint --- composer.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index a2a2661..194efbe 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "php": "^8.0", "ext-json": "*", "codeception/codeception": "*@dev", - "codeception/lib-innerbrowser": "^3.0", + "codeception/lib-innerbrowser": "*@dev", "guzzlehttp/guzzle": "^7.4" }, "require-dev": { @@ -30,7 +30,8 @@ "codeception/module-rest": "^2.0 || *@dev" }, "conflict": { - "codeception/codeception": "<5.0" + "codeception/codeception": "<5.0", + "codeception/lib-innerbrowser": "<3.0" }, "suggest": { "codeception/phpbuiltinserver": "Start and stop PHP built-in web server for your tests" From 4429d7ec8484c85b006a745016783c1a27e2a27d Mon Sep 17 00:00:00 2001 From: Arhell Date: Sat, 19 Feb 2022 14:58:20 +0200 Subject: [PATCH 21/26] update links --- src/Codeception/Module/PhpBrowser.php | 8 ++++---- tests/data/app/view/external_url.php | 2 +- tests/unit/Codeception/Module/PhpBrowserTest.php | 4 ++-- tests/unit/Codeception/Module/TestsForBrowsers.php | 4 ++-- tests/unit/Codeception/Module/TestsForWeb.php | 12 ++++++------ 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Codeception/Module/PhpBrowser.php b/src/Codeception/Module/PhpBrowser.php index 0222876..6b6f90e 100644 --- a/src/Codeception/Module/PhpBrowser.php +++ b/src/Codeception/Module/PhpBrowser.php @@ -33,13 +33,13 @@ * * * url *required* - start url of your app * * headers - default headers are set before each test. - * * handler (default: curl) - Guzzle handler to use. By default curl is used, also possible to pass `stream`, or any valid class name as [Handler](http://docs.guzzlephp.org/en/latest/handlers-and-middleware.html#handlers). + * * handler (default: curl) - Guzzle handler to use. By default curl is used, also possible to pass `stream`, or any valid class name as [Handler](https://docs.guzzlephp.org/en/latest/handlers-and-middleware.html#handlers). * * middleware - Guzzle middlewares to add. An array of valid callables is required. * * curl - curl options * * cookies - ... * * auth - ... * * verify - ... - * * .. those and other [Guzzle Request options](http://docs.guzzlephp.org/en/latest/request-options.html) + * * .. those and other [Guzzle Request options](https://docs.guzzlephp.org/en/latest/request-options.html) * * * ### Example (`acceptance.suite.yml`) @@ -74,7 +74,7 @@ * * Properties: * - * * `guzzle` - contains [Guzzle](http://guzzlephp.org/) client instance: `\GuzzleHttp\Client` + * * `guzzle` - contains [Guzzle](https://guzzlephp.org/) client instance: `\GuzzleHttp\Client` * * `client` - Symfony BrowserKit instance. * */ @@ -193,7 +193,7 @@ protected function onReconfigure() /** * Low-level API method. - * If Codeception commands are not enough, use [Guzzle HTTP Client](http://guzzlephp.org/) methods directly + * If Codeception commands are not enough, use [Guzzle HTTP Client](https://guzzlephp.org/) methods directly * * Example: * diff --git a/tests/data/app/view/external_url.php b/tests/data/app/view/external_url.php index 4b2be70..ca0435a 100644 --- a/tests/data/app/view/external_url.php +++ b/tests/data/app/view/external_url.php @@ -1,5 +1,5 @@ - Next + Next \ No newline at end of file diff --git a/tests/unit/Codeception/Module/PhpBrowserTest.php b/tests/unit/Codeception/Module/PhpBrowserTest.php index c9127c7..1d9e39d 100644 --- a/tests/unit/Codeception/Module/PhpBrowserTest.php +++ b/tests/unit/Codeception/Module/PhpBrowserTest.php @@ -512,11 +512,11 @@ public function testCookiesForDomain() $handler = GuzzleHandlerStack::create($mock); $handler->push(GuzzleMiddleware::history($this->history)); - $client = new GuzzleClient(['handler' => $handler, 'base_uri' => 'http://codeception.com']); + $client = new GuzzleClient(['handler' => $handler, 'base_uri' => 'https://codeception.com']); $guzzleConnector = new Guzzle(); $guzzleConnector->setClient($client); $guzzleConnector->getCookieJar()->set(new Cookie('hello', 'world')); - $guzzleConnector->request('GET', 'http://codeception.com/'); + $guzzleConnector->request('GET', 'https://codeception.com/'); $this->assertArrayHasKey('cookies', $this->history[0]['options']); /** @var $cookie GuzzleHttp\Cookie\SetCookie **/ $cookies = $this->history[0]['options']['cookies']->toArray(); diff --git a/tests/unit/Codeception/Module/TestsForBrowsers.php b/tests/unit/Codeception/Module/TestsForBrowsers.php index ddf2c28..eb42cf8 100644 --- a/tests/unit/Codeception/Module/TestsForBrowsers.php +++ b/tests/unit/Codeception/Module/TestsForBrowsers.php @@ -17,11 +17,11 @@ abstract class TestsForBrowsers extends TestsForWeb public function testAmOnSubdomain() { - $this->module->_reconfigure(['url' => 'http://google.com']); + $this->module->_reconfigure(['url' => 'https://google.com']); $this->module->amOnSubdomain('user'); $this->assertEquals('http://user.google.com', $this->module->_getUrl()); - $this->module->_reconfigure(['url' => 'http://www.google.com']); + $this->module->_reconfigure(['url' => 'https://www.google.com']); $this->module->amOnSubdomain('user'); $this->assertEquals('http://user.google.com', $this->module->_getUrl()); } diff --git a/tests/unit/Codeception/Module/TestsForWeb.php b/tests/unit/Codeception/Module/TestsForWeb.php index f4c817d..a15e114 100644 --- a/tests/unit/Codeception/Module/TestsForWeb.php +++ b/tests/unit/Codeception/Module/TestsForWeb.php @@ -119,9 +119,9 @@ public function testSeeLink() { $this->module->amOnPage('/external_url'); $this->module->seeLink('Next'); - $this->module->seeLink('Next', 'http://codeception.com/'); + $this->module->seeLink('Next', 'https://codeception.com/'); // Without TLD and trailing slash - $this->module->dontSeeLink('Next', 'http://codeception'); + $this->module->dontSeeLink('Next', 'https://codeception'); } public function testDontSeeLink() @@ -150,9 +150,9 @@ public function testSeeLinkFailsIfHrefDoesNotMatch() public function testSeeLinkFailsIfHrefDoesNotMatchExactly() { $this->expectException(AssertionFailedError::class); - $this->expectExceptionMessage("No links containing text 'Next' and URL 'http://codeception' were found in page /external_url"); + $this->expectExceptionMessage("No links containing text 'Next' and URL 'https://codeception' were found in page /external_url"); $this->module->amOnPage('/external_url'); - $this->module->seeLink('Next', 'http://codeception'); + $this->module->seeLink('Next', 'https://codeception'); } public function testDontSeeLinkFailsIfTextMatches() @@ -166,9 +166,9 @@ public function testDontSeeLinkFailsIfTextMatches() public function testDontSeeLinkFailsIfTextAndUrlMatches() { $this->expectException(AssertionFailedError::class); - $this->expectExceptionMessage("Link containing text 'Next' and URL 'http://codeception.com/' was found in page /external_url"); + $this->expectExceptionMessage("Link containing text 'Next' and URL 'https://codeception.com/' was found in page /external_url"); $this->module->amOnPage('/external_url'); - $this->module->dontSeeLink('Next', 'http://codeception.com/'); + $this->module->dontSeeLink('Next', 'https://codeception.com/'); } public function testSeeLinkMatchesRelativeLink() From 9d2242cb305966cd8c965f83a61c8044c1c9be6f Mon Sep 17 00:00:00 2001 From: Gintautas Miselis Date: Sat, 19 Feb 2022 20:09:18 +0200 Subject: [PATCH 22/26] Add restrictions for symfony/browser-kit Because symfony/browser-kit 4.4 is not supported --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 194efbe..a9ec5d9 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,8 @@ "ext-json": "*", "codeception/codeception": "*@dev", "codeception/lib-innerbrowser": "*@dev", - "guzzlehttp/guzzle": "^7.4" + "guzzlehttp/guzzle": "^7.4", + "symfony/browser-kit": "^5.4 || ^6.0" }, "require-dev": { "ext-curl": "*", From 70c9934a118638a96f5efad290f15a568a11d583 Mon Sep 17 00:00:00 2001 From: Gintautas Miselis Date: Sat, 19 Feb 2022 20:21:21 +0200 Subject: [PATCH 23/26] Fix broken test --- tests/unit/Codeception/Module/TestsForBrowsers.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/Codeception/Module/TestsForBrowsers.php b/tests/unit/Codeception/Module/TestsForBrowsers.php index eb42cf8..3edac74 100644 --- a/tests/unit/Codeception/Module/TestsForBrowsers.php +++ b/tests/unit/Codeception/Module/TestsForBrowsers.php @@ -19,11 +19,11 @@ public function testAmOnSubdomain() { $this->module->_reconfigure(['url' => 'https://google.com']); $this->module->amOnSubdomain('user'); - $this->assertEquals('http://user.google.com', $this->module->_getUrl()); + $this->assertEquals('https://user.google.com', $this->module->_getUrl()); $this->module->_reconfigure(['url' => 'https://www.google.com']); $this->module->amOnSubdomain('user'); - $this->assertEquals('http://user.google.com', $this->module->_getUrl()); + $this->assertEquals('https://user.google.com', $this->module->_getUrl()); } public function testOpenAbsoluteUrls() From aa95507c6b0d3b96a0b8df12ff8cb970ec82e1ff Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Thu, 30 Nov 2023 13:15:47 +0100 Subject: [PATCH 24/26] Updating `composer.json` for Symfony 7.0 I didn't check if it really works... --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a9ec5d9..a9c2509 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ "codeception/codeception": "*@dev", "codeception/lib-innerbrowser": "*@dev", "guzzlehttp/guzzle": "^7.4", - "symfony/browser-kit": "^5.4 || ^6.0" + "symfony/browser-kit": "^5.4 || ^6.0 || ^7.0" }, "require-dev": { "ext-curl": "*", From 8a7f950263575ed5daec523878cd3dfaaa2a4e30 Mon Sep 17 00:00:00 2001 From: Cristi Radu Date: Sun, 28 Jul 2024 08:27:45 +0300 Subject: [PATCH 25/26] Modernize codebase and add more code quality tools (#37) * Added github actions for php 8.2 and 8.3 * Create dependabot.yml * Added more code quality tools --------- Co-authored-by: TavoNiievez --- .github/dependabot.yml | 11 + .github/workflows/main.yml | 10 +- composer.json | 9 +- phpcs.xml | 23 ++ phpstan.neon | 4 + src/Codeception/Lib/Connector/Guzzle.php | 58 ++- src/Codeception/Module/PhpBrowser.php | 40 ++- tests/_support/UnitTester.php | 1 - tests/data/app/controllers.php | 263 +++++++++----- tests/data/app/data.php | 16 +- tests/data/app/glue.php | 73 ++-- tests/data/app/index.php | 7 +- tests/data/app/view/form/bug3824.php | 6 +- tests/data/app/view/form/complex.php | 2 +- tests/data/app/view/form/unchecked.php | 8 +- tests/data/app/view/index.php | 4 +- tests/data/app/view/info.php | 4 +- tests/data/app/view/search.php | 6 +- tests/data/rest/index.php | 14 +- tests/data/rest/server.php | 8 +- .../Codeception/Module/PhpBrowserRestTest.php | 226 ++++++------ .../Codeception/Module/PhpBrowserTest.php | 166 +++++---- .../Codeception/Module/TestsForBrowsers.php | 13 +- tests/unit/Codeception/Module/TestsForWeb.php | 336 +++++++++--------- 24 files changed, 727 insertions(+), 581 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 phpcs.xml create mode 100644 phpstan.neon diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..b01043c --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +version: 2 +updates: + - + package-ecosystem: composer + directory: "/" + schedule: + interval: monthly + versioning-strategy: auto + groups: + dev-dependencies: + dependency-type: "development" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f3b7f28..879203e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,11 +8,11 @@ jobs: strategy: matrix: - php: [8.0, 8.1] + php: [8.1, 8.2, 8.3] steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -26,6 +26,12 @@ jobs: - name: Install dependencies run: composer install --prefer-dist --no-progress --no-interaction --no-suggest + - name: Execute Code Sniffer + run: vendor/bin/phpcs + + - name: Execute PHP Stan + run: vendor/bin/phpstan + - name: Run test suite run: | php -S 127.0.0.1:8000 -t tests/data/app >/dev/null 2>&1 & diff --git a/composer.json b/composer.json index a9c2509..ce86167 100644 --- a/composer.json +++ b/composer.json @@ -18,17 +18,19 @@ ], "homepage": "https://codeception.com/", "require": { - "php": "^8.0", + "php": "^8.1", "ext-json": "*", "codeception/codeception": "*@dev", "codeception/lib-innerbrowser": "*@dev", "guzzlehttp/guzzle": "^7.4", - "symfony/browser-kit": "^5.4 || ^6.0 || ^7.0" + "symfony/browser-kit": "^5.4 | ^6.0 | ^7.0" }, "require-dev": { "ext-curl": "*", + "squizlabs/php_codesniffer": "^3.10", + "phpstan/phpstan": "^1.10", "aws/aws-sdk-php": "^3.199", - "codeception/module-rest": "^2.0 || *@dev" + "codeception/module-rest": "^2.0 | *@dev" }, "conflict": { "codeception/codeception": "<5.0", @@ -37,7 +39,6 @@ "suggest": { "codeception/phpbuiltinserver": "Start and stop PHP built-in web server for your tests" }, - "minimum-stability": "dev", "autoload": { "classmap": [ "src/" diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..7b36367 --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,23 @@ + + + The coding standard. + + + + src + + + + + + + + error + + + + + + warning + + \ No newline at end of file diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..dec5108 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,4 @@ +parameters: + paths: + - ./src + level: 5 \ No newline at end of file diff --git a/src/Codeception/Lib/Connector/Guzzle.php b/src/Codeception/Lib/Connector/Guzzle.php index 3816b1d..55594bd 100644 --- a/src/Codeception/Lib/Connector/Guzzle.php +++ b/src/Codeception/Lib/Connector/Guzzle.php @@ -23,6 +23,9 @@ class Guzzle extends AbstractBrowser { + /** + * @var array + */ protected array $requestOptions = [ 'allow_redirects' => false, 'headers' => [], @@ -115,7 +118,7 @@ protected function createResponse(Psr7Response $psr7Response): BrowserKitRespons $contentType = 'text/html'; } - if (strpos($contentType, 'charset=') === false) { + if (str_contains($contentType, 'charset=') === false) { if (preg_match('#]+charset *= *["\']?([a-zA-Z\-0-9]+)#i', $body, $matches)) { $contentType .= ';charset=' . $matches[1]; } @@ -159,10 +162,10 @@ protected function createResponse(Psr7Response $psr7Response): BrowserKitRespons protected function getAbsoluteUri(string $uri): string { $baseUri = $this->client->getConfig('base_uri'); - if (strpos($uri, '://') === false && strpos($uri, '//') !== 0) { - if (strpos($uri, '/') === 0) { + if (str_contains($uri, '://') === false && !str_starts_with($uri, '//')) { + if (str_starts_with($uri, '/')) { $baseUriPath = $baseUri->getPath(); - if (!empty($baseUriPath) && strpos($uri, (string) $baseUriPath) === 0) { + if (!empty($baseUriPath) && str_starts_with($uri, (string) $baseUriPath)) { $uri = substr($uri, strlen($baseUriPath)); } @@ -178,9 +181,9 @@ protected function getAbsoluteUri(string $uri): string return Uri::mergeUrls((string)$baseUri, $uri); } - protected function doRequest($request) + protected function doRequest(object $request) { - /** @var $request BrowserKitRequest **/ + /** @var BrowserKitRequest $request **/ $guzzleRequest = new Psr7Request( $request->getMethod(), $request->getUri(), @@ -190,17 +193,17 @@ protected function doRequest($request) $options = $this->requestOptions; $options['cookies'] = $this->extractCookies($guzzleRequest->getUri()->getHost()); $multipartData = $this->extractMultipartFormData($request); - if (!empty($multipartData)) { + if ($multipartData !== []) { $options['multipart'] = $multipartData; } $formData = $this->extractFormData($request); - if (empty($multipartData) && $formData) { + if ($multipartData === [] && $formData) { $options['form_params'] = $formData; } try { - if (null !== $this->awsCredentials) { + if ($this->awsCredentials instanceof AwsCredentials) { $response = $this->client->send($this->awsSignature->signRequest($guzzleRequest, $this->awsCredentials), $options); } else { $response = $this->client->send($guzzleRequest, $options); @@ -213,6 +216,7 @@ protected function doRequest($request) $response = $exception->getResponse(); } + // @phpstan-ignore-next-line return $this->createResponse($response); } @@ -227,7 +231,7 @@ protected function extractHeaders(BrowserKitRequest $request): array $contentHeaders = ['Content-Length' => true, 'Content-Md5' => true, 'Content-Type' => true]; foreach ($server as $header => $val) { $header = html_entity_decode(implode('-', array_map('ucfirst', explode('-', strtolower(str_replace('_', '-', $header))))), ENT_NOQUOTES); - if (strpos($header, 'Http-') === 0) { + if (str_starts_with($header, 'Http-')) { $headers[substr($header, 5)] = $val; } elseif (isset($contentHeaders[$header])) { $headers[$header] = $val; @@ -237,6 +241,9 @@ protected function extractHeaders(BrowserKitRequest $request): array return $headers; } + /** + * @return array|null + */ protected function extractFormData(BrowserKitRequest $browserKitRequest): ?array { if (!in_array(strtoupper($browserKitRequest->getMethod()), ['POST', 'PUT', 'PATCH', 'DELETE'])) { @@ -257,14 +264,17 @@ protected function extractFormData(BrowserKitRequest $browserKitRequest): ?array return $browserKitRequest->getParameters(); } - protected function extractMultipartFormData(BrowserKitRequest $browserKitRequest) + /** + * @return array + */ + protected function extractMultipartFormData(BrowserKitRequest $browserKitRequest): array { if (!in_array(strtoupper($browserKitRequest->getMethod()), ['POST', 'PUT', 'PATCH'])) { return []; } $parts = $this->mapFiles($browserKitRequest->getFiles()); - if (empty($parts)) { + if ($parts === []) { return []; } @@ -275,11 +285,14 @@ protected function extractMultipartFormData(BrowserKitRequest $browserKitRequest return $parts; } - protected function formatMultipart($parts, $key, $value) + /** + * @return array + */ + protected function formatMultipart(mixed $parts, string $key, mixed $value): array { if (is_array($value)) { foreach ($value as $subKey => $subValue) { - $parts = array_merge($this->formatMultipart([], $key.sprintf('[%s]', $subKey), $subValue), $parts); + $parts = array_merge($this->formatMultipart([], $key . sprintf('[%s]', $subKey), $subValue), $parts); } return $parts; @@ -289,7 +302,11 @@ protected function formatMultipart($parts, $key, $value) return $parts; } - protected function mapFiles($requestFiles, $arrayName = ''): array + /** + * @param array $requestFiles + * @return array + */ + protected function mapFiles(array $requestFiles, ?string $arrayName = ''): array { $files = []; foreach ($requestFiles as $name => $info) { @@ -329,7 +346,7 @@ protected function mapFiles($requestFiles, $arrayName = ''): array return $files; } - protected function extractCookies($host): GuzzleCookieJar + protected function extractCookies(string $host): GuzzleCookieJar { $jar = []; $cookies = $this->getCookieJar()->all(); @@ -345,7 +362,7 @@ protected function extractCookies($host): GuzzleCookieJar return new GuzzleCookieJar(false, $jar); } - public static function createHandler($handler): GuzzleHandlerStack + public static function createHandler(mixed $handler): GuzzleHandlerStack { if ($handler instanceof GuzzleHandlerStack) { return $handler; @@ -360,7 +377,7 @@ public static function createHandler($handler): GuzzleHandlerStack } if (is_string($handler) && class_exists($handler)) { - return GuzzleHandlerStack::create(new $handler); + return GuzzleHandlerStack::create(new $handler()); } if (is_callable($handler)) { @@ -370,7 +387,10 @@ public static function createHandler($handler): GuzzleHandlerStack return GuzzleHandlerStack::create(); } - public function setAwsAuth($config): void + /** + * @param array $config + */ + public function setAwsAuth(array $config): void { $this->awsCredentials = new AwsCredentials($config['key'], $config['secret']); $this->awsSignature = new AwsSignatureV4($config['service'], $config['region']); diff --git a/src/Codeception/Module/PhpBrowser.php b/src/Codeception/Module/PhpBrowser.php index 6b6f90e..5049f5c 100644 --- a/src/Codeception/Module/PhpBrowser.php +++ b/src/Codeception/Module/PhpBrowser.php @@ -135,7 +135,7 @@ public function _initialize() public function _before(TestInterface $test) { - if (!$this->client) { + if (!$this->client instanceof AbstractBrowser) { $this->client = new Guzzle(); } @@ -155,12 +155,14 @@ public function setHeader(string $name, string $value): void $this->haveHttpHeader($name, $value); } - public function amHttpAuthenticated($username, $password): void + public function amHttpAuthenticated(string $username, string $password): void { - $this->client->setAuth($username, $password); + if ($this->client instanceof Guzzle) { + $this->client->setAuth($username, $password); + } } - public function amOnUrl($url): void + public function amOnUrl(string $url): void { $host = Uri::retrieveHost($url); $config = $this->config; @@ -175,7 +177,7 @@ public function amOnUrl($url): void $this->amOnPage($page); } - public function amOnSubdomain($subdomain): void + public function amOnSubdomain(string $subdomain): void { $url = $this->config['url']; $url = preg_replace('#(https?://)(.*\.)(.*\.)#', "$1$3", $url); // removing current subdomain @@ -206,18 +208,13 @@ protected function onReconfigure() * * It is not recommended to use this command on a regular basis. * If Codeception lacks important Guzzle Client methods, implement them and submit patches. - * - * @return mixed */ - public function executeInGuzzle(Closure $function) + public function executeInGuzzle(Closure $function): mixed { return $function($this->guzzle); } - /** - * @return int|string - */ - public function _getResponseCode() + public function _getResponseCode(): int|string { return $this->getResponseStatusCode(); } @@ -245,21 +242,24 @@ public function _prepareSession(): void $defaults['base_uri'] = $this->config['url']; $defaults['curl'] = $curlOptions; - $handler = Guzzle::createHandler($this->config['handler']); - if ($handler && is_array($this->config['middleware'])) { + $handlerStack = Guzzle::createHandler($this->config['handler']); + if (is_array($this->config['middleware'])) { foreach ($this->config['middleware'] as $middleware) { - $handler->push($middleware); + $handlerStack->push($middleware); } } - $defaults['handler'] = $handler; + $defaults['handler'] = $handlerStack; $this->guzzle = new GuzzleClient($defaults); $this->client->setRefreshMaxInterval($this->config['refresh_max_interval']); $this->client->setClient($this->guzzle); } - public function _backupSession(): array + /** + * @return array + */ + public function _backupSession() { return [ 'client' => $this->client, @@ -269,6 +269,9 @@ public function _backupSession(): array ]; } + /** + * @param array $session + */ public function _loadSession($session): void { foreach ($session as $key => $val) { @@ -276,6 +279,9 @@ public function _loadSession($session): void } } + /** + * @param ?array $session + */ public function _closeSession($session = null): void { unset($session); diff --git a/tests/_support/UnitTester.php b/tests/_support/UnitTester.php index e19544a..6aeac82 100644 --- a/tests/_support/UnitTester.php +++ b/tests/_support/UnitTester.php @@ -1,6 +1,5 @@ GET(); } } -class contentType1 { - function GET() { +class contentType1 +{ + function GET() + { header('Content-Type:', true); - include __DIR__.'/view/content_type.php'; + include __DIR__ . '/view/content_type.php'; } } -class contentType2 { - function GET() { +class contentType2 +{ + function GET() + { header('Content-Type:', true); - include __DIR__.'/view/content_type2.php'; + include __DIR__ . '/view/content_type2.php'; } } -class unsetCookie { - function GET() { +class unsetCookie +{ + function GET() + { header('Set-Cookie: a=; Expires=Thu, 01 Jan 1970 00:00:01 GMT'); } } -class basehref { - function GET() { - include __DIR__.'/view/basehref.php'; +class basehref +{ + function GET() + { + include __DIR__ . '/view/basehref.php'; } } -class jserroronload { - function GET() { - include __DIR__.'/view/jserroronload.php'; +class jserroronload +{ + function GET() + { + include __DIR__ . '/view/jserroronload.php'; } } -class userAgent { - function GET() { +class userAgent +{ + function GET() + { echo $_SERVER['HTTP_USER_AGENT']; } } -class minimal { - function GET() { - include __DIR__.'/view/minimal.php'; +class minimal +{ + function GET() + { + include __DIR__ . '/view/minimal.php'; } } diff --git a/tests/data/app/data.php b/tests/data/app/data.php index c1877c2..d7dca0e 100755 --- a/tests/data/app/data.php +++ b/tests/data/app/data.php @@ -1,9 +1,11 @@ $class) { - $regex = str_replace('/', '\/', $regex); - $regex = '^' . $regex . '\/?$'; - if (preg_match("/$regex/i", $path, $matches)) { - $found = true; - if (class_exists($class)) { - $obj = new $class; - if (method_exists($obj, $method)) { - $obj->$method($matches); - } else { - throw new BadMethodCallException("Method, $method, not supported."); - } + foreach ($urls as $regex => $class) { + $regex = str_replace('/', '\/', $regex); + $regex = '^' . $regex . '\/?$'; + if (preg_match("/$regex/i", $path, $matches)) { + $found = true; + if (class_exists($class)) { + $obj = new $class(); + if (method_exists($obj, $method)) { + $obj->$method($matches); } else { - throw new Exception("Class, $class, not found."); + throw new BadMethodCallException("Method, $method, not supported."); } - break; + } else { + throw new Exception("Class, $class, not found."); } + break; } - if (!$found) { - throw new Exception("URL, $path, not found."); - } + } + if (!$found) { + throw new Exception("URL, $path, not found."); } } +} diff --git a/tests/data/app/index.php b/tests/data/app/index.php index 4c65804..243d816 100644 --- a/tests/data/app/index.php +++ b/tests/data/app/index.php @@ -1,10 +1,12 @@ 'index', '/info' => 'info', @@ -42,5 +44,4 @@ '/jserroronload' => 'jserroronload', '/minimal' => 'minimal', ); - glue::stick($urls); diff --git a/tests/data/app/view/form/bug3824.php b/tests/data/app/view/form/bug3824.php index 221fb98..64a02ff 100644 --- a/tests/data/app/view/form/bug3824.php +++ b/tests/data/app/view/form/bug3824.php @@ -7,9 +7,9 @@ diff --git a/tests/data/app/view/form/complex.php b/tests/data/app/view/form/complex.php index 272bd84..dd35b91 100755 --- a/tests/data/app/view/form/complex.php +++ b/tests/data/app/view/form/complex.php @@ -41,4 +41,4 @@ - \ No newline at end of file + diff --git a/tests/data/app/view/form/unchecked.php b/tests/data/app/view/form/unchecked.php index 2e8848e..30fcbdf 100644 --- a/tests/data/app/view/form/unchecked.php +++ b/tests/data/app/view/form/unchecked.php @@ -8,10 +8,10 @@
- \ No newline at end of file + diff --git a/tests/data/app/view/index.php b/tests/data/app/view/index.php index 3890759..5157fab 100755 --- a/tests/data/app/view/index.php +++ b/tests/data/app/view/index.php @@ -4,7 +4,9 @@

Welcome to test app!

-
+

More info diff --git a/tests/data/app/view/info.php b/tests/data/app/view/info.php index b8041ef..65c2ea9 100755 --- a/tests/data/app/view/info.php +++ b/tests/data/app/view/info.php @@ -12,7 +12,9 @@ Back

-
+

Don't do that at home!

diff --git a/tests/data/app/view/search.php b/tests/data/app/view/search.php index 8c4de1d..ba457a8 100644 --- a/tests/data/app/view/search.php +++ b/tests/data/app/view/search.php @@ -5,7 +5,9 @@
- +
- \ No newline at end of file + diff --git a/tests/data/rest/index.php b/tests/data/rest/index.php index c04ebaa..c5d77ac 100755 --- a/tests/data/rest/index.php +++ b/tests/data/rest/index.php @@ -5,7 +5,7 @@ $GLOBALS['RESTmap'] = []; $GLOBALS['RESTmap']['GET'] = [ - 'user' => function() { + 'user' => function () { return [ 'name' => 'davert', 'email' => 'davert@mail.ua', @@ -18,7 +18,7 @@ 'country' => 'Ukraine', ]]; }, - 'zeroes' => function() { + 'zeroes' => function () { return [ 'responseCode' => 0, 'message' => 'OK', @@ -29,7 +29,7 @@ ], ]; }, - 'foo' => function() { + 'foo' => function () { if (isset($_SERVER['HTTP_FOO'])) { return 'foo: "' . $_SERVER['HTTP_FOO'] . '"'; } @@ -39,11 +39,11 @@ ]; $GLOBALS['RESTmap']['POST'] = [ - 'user' => function() { + 'user' => function () { $name = $_POST['name']; return ['name' => $name]; }, - 'file-upload' => function() { + 'file-upload' => function () { return [ 'uploaded' => isset($_FILES['file']['tmp_name']) && file_exists($_FILES['file']['tmp_name']), ]; @@ -51,7 +51,7 @@ ]; $GLOBALS['RESTmap']['PUT'] = [ - 'user' => function() { + 'user' => function () { $name = $_REQUEST['name']; $user = ['name' => 'davert', 'email' => 'davert@mail.ua']; $user['name'] = $name; @@ -60,7 +60,7 @@ ]; $GLOBALS['RESTmap']['DELETE'] = [ - 'user' => function() { + 'user' => function () { header('error', false, 404); } ]; diff --git a/tests/data/rest/server.php b/tests/data/rest/server.php index 70e241c..ba051a4 100755 --- a/tests/data/rest/server.php +++ b/tests/data/rest/server.php @@ -1,8 +1,9 @@ phpBrowser = new PhpBrowser($container); @@ -26,140 +26,140 @@ protected function _setUp() $this->phpBrowser->_setConfig(['url' => $url]); $this->phpBrowser->_initialize(); - $this->module = Stub::make(REST::class); - $this->module->_inject($this->phpBrowser); - $this->module->_initialize(); - $this->module->_before(Stub::makeEmpty(Cest::class)); - + $this->rest = Stub::make(REST::class); + $this->rest->_inject($this->phpBrowser); + $this->rest->_initialize(); + $this->rest->_before(Stub::makeEmpty(Cest::class)); + $this->phpBrowser->_before(Stub::makeEmpty(Cest::class)); } - private function setStubResponse($response) + private function setStubResponse($response): void { $this->phpBrowser = Stub::make(PhpBrowser::class, ['_getResponseContent' => $response]); - $this->module->_inject($this->phpBrowser); - $this->module->_initialize(); - $this->module->_before(Stub::makeEmpty(Cest::class)); + $this->rest->_inject($this->phpBrowser); + $this->rest->_initialize(); + $this->rest->_before(Stub::makeEmpty(Cest::class)); } - public function testGet() + public function testGet(): void { - $this->module->sendGET('/rest/user/'); - $this->module->seeResponseIsJson(); - $this->module->seeResponseContains('davert'); - $this->module->seeResponseContainsJson(['name' => 'davert']); - $this->module->seeResponseCodeIs(200); - $this->module->dontSeeResponseCodeIs(404); + $this->rest->sendGET('/rest/user/'); + $this->rest->seeResponseIsJson(); + $this->rest->seeResponseContains('davert'); + $this->rest->seeResponseContainsJson(['name' => 'davert']); + $this->rest->seeResponseCodeIs(200); + $this->rest->dontSeeResponseCodeIs(404); } - public function testSendAbsoluteUrlGet() + public function testSendAbsoluteUrlGet(): void { - $this->module->sendGET('http://127.0.0.1:8010/rest/user/'); - $this->module->seeResponseCodeIs(200); + $this->rest->sendGET('http://127.0.0.1:8010/rest/user/'); + $this->rest->seeResponseCodeIs(200); } - public function testPost() + public function testPost(): void { - $this->module->sendPOST('/rest/user/', ['name' => 'john']); - $this->module->seeResponseContains('john'); - $this->module->seeResponseContainsJson(['name' => 'john']); + $this->rest->sendPOST('/rest/user/', ['name' => 'john']); + $this->rest->seeResponseContains('john'); + $this->rest->seeResponseContainsJson(['name' => 'john']); } - public function testValidJson() + public function testValidJson(): void { $this->setStubResponse('{"xxx": "yyy"}'); - $this->module->seeResponseIsJson(); + $this->rest->seeResponseIsJson(); $this->setStubResponse('{"xxx": "yyy", "zzz": ["a","b"]}'); - $this->module->seeResponseIsJson(); - $this->module->seeResponseEquals('{"xxx": "yyy", "zzz": ["a","b"]}'); + $this->rest->seeResponseIsJson(); + $this->rest->seeResponseEquals('{"xxx": "yyy", "zzz": ["a","b"]}'); } - public function testInvalidJson() + public function testInvalidJson(): void { $this->expectException(ExpectationFailedException::class); $this->setStubResponse('{xxx = yyy}'); - $this->module->seeResponseIsJson(); + $this->rest->seeResponseIsJson(); } - public function testValidXml() + public function testValidXml(): void { $this->setStubResponse(''); - $this->module->seeResponseIsXml(); + $this->rest->seeResponseIsXml(); $this->setStubResponse('John'); - $this->module->seeResponseIsXml(); - $this->module->seeResponseEquals('John'); + $this->rest->seeResponseIsXml(); + $this->rest->seeResponseEquals('John'); } - public function testInvalidXml() + public function testInvalidXml(): void { $this->expectException(ExpectationFailedException::class); $this->setStubResponse('John'); - $this->module->seeResponseIsXml(); + $this->rest->seeResponseIsXml(); } - public function testSeeInJson() + public function testSeeInJson(): void { $this->setStubResponse( '{"ticket": {"title": "Bug should be fixed", "user": {"name": "Davert"}, "labels": null}}' ); - $this->module->seeResponseIsJson(); - $this->module->seeResponseContainsJson(['name' => 'Davert']); - $this->module->seeResponseContainsJson(['user' => ['name' => 'Davert']]); - $this->module->seeResponseContainsJson(['ticket' => ['title' => 'Bug should be fixed']]); - $this->module->seeResponseContainsJson(['ticket' => ['user' => ['name' => 'Davert']]]); - $this->module->seeResponseContainsJson(['ticket' => ['labels' => null]]); + $this->rest->seeResponseIsJson(); + $this->rest->seeResponseContainsJson(['name' => 'Davert']); + $this->rest->seeResponseContainsJson(['user' => ['name' => 'Davert']]); + $this->rest->seeResponseContainsJson(['ticket' => ['title' => 'Bug should be fixed']]); + $this->rest->seeResponseContainsJson(['ticket' => ['user' => ['name' => 'Davert']]]); + $this->rest->seeResponseContainsJson(['ticket' => ['labels' => null]]); } - public function testSeeInJsonCollection() + public function testSeeInJsonCollection(): void { $this->setStubResponse( '[{"user":"Blacknoir","age":27,"tags":["wed-dev","php"]},' . '{"user":"John Doe","age":27,"tags":["web-dev","java"]}]' ); - $this->module->seeResponseIsJson(); - $this->module->seeResponseContainsJson(['tags' => ['web-dev', 'java']]); - $this->module->seeResponseContainsJson(['user' => 'John Doe', 'age' => 27]); + $this->rest->seeResponseIsJson(); + $this->rest->seeResponseContainsJson(['tags' => ['web-dev', 'java']]); + $this->rest->seeResponseContainsJson(['user' => 'John Doe', 'age' => 27]); } - public function testArrayJson() + public function testArrayJson(): void { $this->setStubResponse( '[{"id":1,"title": "Bug should be fixed"},{"title": "Feature should be implemented","id":2}]' ); - $this->module->seeResponseContainsJson(['id' => 1]); + $this->rest->seeResponseContainsJson(['id' => 1]); } /** * @issue https://github.com/Codeception/Codeception/issues/4202 */ - public function testSeeResponseContainsJsonFailsGracefullyWhenJsonResultIsNotArray() + public function testSeeResponseContainsJsonFailsGracefullyWhenJsonResultIsNotArray(): void { $this->shouldFail(); $this->setStubResponse(json_encode('no_status', JSON_THROW_ON_ERROR)); - $this->module->seeResponseContainsJson(['id' => 1]); + $this->rest->seeResponseContainsJson(['id' => 1]); } - public function testDontSeeResponseJsonMatchesJsonPathPassesWhenJsonResultIsNotArray() + public function testDontSeeResponseJsonMatchesJsonPathPassesWhenJsonResultIsNotArray(): void { $this->setStubResponse(json_encode('no_status', JSON_THROW_ON_ERROR)); - $this->module->dontSeeResponseJsonMatchesJsonPath('$.error'); + $this->rest->dontSeeResponseJsonMatchesJsonPath('$.error'); } - public function testDontSeeInJson() + public function testDontSeeInJson(): void { $this->setStubResponse('{"ticket": {"title": "Bug should be fixed", "user": {"name": "Davert"}}}'); - $this->module->seeResponseIsJson(); - $this->module->dontSeeResponseContainsJson(['name' => 'Davet']); - $this->module->dontSeeResponseContainsJson(['user' => ['name' => 'Davet']]); - $this->module->dontSeeResponseContainsJson(['user' => ['title' => 'Bug should be fixed']]); + $this->rest->seeResponseIsJson(); + $this->rest->dontSeeResponseContainsJson(['name' => 'Davet']); + $this->rest->dontSeeResponseContainsJson(['user' => ['name' => 'Davet']]); + $this->rest->dontSeeResponseContainsJson(['user' => ['title' => 'Bug should be fixed']]); } - public function testApplicationJsonIncludesJsonAsContent() + public function testApplicationJsonIncludesJsonAsContent(): void { - $this->module->haveHttpHeader('Content-Type', 'application/json'); - $this->module->sendPOST('/', ['name' => 'john']); + $this->rest->haveHttpHeader('Content-Type', 'application/json'); + $this->rest->sendPOST('/', ['name' => 'john']); /** @var $request SymfonyRequest **/ - $request = $this->module->client->getRequest(); + $request = $this->rest->client->getRequest(); $this->assertContains('application/json', $request->getServer()); $server = $request->getServer(); $this->assertEquals('application/json', $server['HTTP_CONTENT_TYPE']); @@ -170,24 +170,24 @@ public function testApplicationJsonIncludesJsonAsContent() /** * @issue https://github.com/Codeception/Codeception/issues/3516 */ - public function testApplicationJsonHeaderCheckIsCaseInsensitive() + public function testApplicationJsonHeaderCheckIsCaseInsensitive(): void { - $this->module->haveHttpHeader('content-type', 'application/json'); - $this->module->sendPOST('/', ['name' => 'john']); + $this->rest->haveHttpHeader('content-type', 'application/json'); + $this->rest->sendPOST('/', ['name' => 'john']); /** @var $request SymfonyRequest **/ - $request = $this->module->client->getRequest(); + $request = $this->rest->client->getRequest(); $server = $request->getServer(); $this->assertEquals('application/json', $server['HTTP_CONTENT_TYPE']); $this->assertJson($request->getContent()); $this->assertEmpty($request->getParameters()); } - public function testGetApplicationJsonNotIncludesJsonAsContent() + public function testGetApplicationJsonNotIncludesJsonAsContent(): void { - $this->module->haveHttpHeader('Content-Type', 'application/json'); - $this->module->sendGET('/', ['name' => 'john']); + $this->rest->haveHttpHeader('Content-Type', 'application/json'); + $this->rest->sendGET('/', ['name' => 'john']); /** @var $request SymfonyRequest **/ - $request = $this->module->client->getRequest(); + $request = $this->rest->client->getRequest(); $this->assertNull($request->getContent()); $this->assertContains('john', $request->getParameters()); } @@ -196,40 +196,40 @@ public function testGetApplicationJsonNotIncludesJsonAsContent() * @Issue https://github.com/Codeception/Codeception/issues/2075 * Client is undefined for the second test */ - public function testTwoTests() + public function testTwoTests(): void { $cest1 = Stub::makeEmpty(Cest::class); $cest2 = Stub::makeEmpty(Cest::class); - $this->module->sendGET('/rest/user/'); - $this->module->seeResponseIsJson(); - $this->module->seeResponseContains('davert'); - $this->module->seeResponseContainsJson(['name' => 'davert']); - $this->module->seeResponseCodeIs(200); - $this->module->dontSeeResponseCodeIs(404); + $this->rest->sendGET('/rest/user/'); + $this->rest->seeResponseIsJson(); + $this->rest->seeResponseContains('davert'); + $this->rest->seeResponseContainsJson(['name' => 'davert']); + $this->rest->seeResponseCodeIs(200); + $this->rest->dontSeeResponseCodeIs(404); $this->phpBrowser->_after($cest1); - $this->module->_after($cest1); - $this->module->_before($cest2); + $this->rest->_after($cest1); + $this->rest->_before($cest2); $this->phpBrowser->_before($cest2); - $this->module->sendGET('/rest/user/'); - $this->module->seeResponseIsJson(); - $this->module->seeResponseContains('davert'); - $this->module->seeResponseContainsJson(['name' => 'davert']); - $this->module->seeResponseCodeIs(200); - $this->module->dontSeeResponseCodeIs(404); + $this->rest->sendGET('/rest/user/'); + $this->rest->seeResponseIsJson(); + $this->rest->seeResponseContains('davert'); + $this->rest->seeResponseContainsJson(['name' => 'davert']); + $this->rest->seeResponseCodeIs(200); + $this->rest->dontSeeResponseCodeIs(404); } - + /** * @Issue https://github.com/Codeception/Codeception/issues/2070 */ - public function testArrayOfZeroesInJsonResponse() + public function testArrayOfZeroesInJsonResponse(): void { - $this->module->haveHttpHeader('Content-Type', 'application/json'); - $this->module->sendGET('/rest/zeroes'); - $this->module->dontSeeResponseContainsJson([ + $this->rest->haveHttpHeader('Content-Type', 'application/json'); + $this->rest->sendGET('/rest/zeroes'); + $this->rest->dontSeeResponseContainsJson([ 'responseCode' => 0, 'data' => [ 0, @@ -239,20 +239,20 @@ public function testArrayOfZeroesInJsonResponse() ]); } - public function testFileUploadWithKeyValueArray() + public function testFileUploadWithKeyValueArray(): void { $tmpFileName = tempnam('/tmp', 'test_'); file_put_contents($tmpFileName, 'test data'); $files = [ 'file' => $tmpFileName, ]; - $this->module->sendPOST('/rest/file-upload', [], $files); - $this->module->seeResponseContainsJson([ + $this->rest->sendPOST('/rest/file-upload', [], $files); + $this->rest->seeResponseContainsJson([ 'uploaded' => true, ]); } - public function testFileUploadWithFilesArray() + public function testFileUploadWithFilesArray(): void { $tmpFileName = tempnam('/tmp', 'test_'); file_put_contents($tmpFileName, 'test data'); @@ -264,48 +264,48 @@ public function testFileUploadWithFilesArray() 'tmp_name' => $tmpFileName, ] ]; - $this->module->sendPOST('/rest/file-upload', [], $files); - $this->module->seeResponseContainsJson([ + $this->rest->sendPOST('/rest/file-upload', [], $files); + $this->rest->seeResponseContainsJson([ 'uploaded' => true, ]); } - public function testCanInspectResultOfPhpBrowserRequest() + public function testCanInspectResultOfPhpBrowserRequest(): void { $this->phpBrowser->amOnPage('/rest/user/'); - $this->module->seeResponseCodeIs(200); - $this->module->seeResponseIsJson(); + $this->rest->seeResponseCodeIs(200); + $this->rest->seeResponseIsJson(); } /** * @Issue 4203 https://github.com/Codeception/Codeception/issues/4203 */ - public function testSessionHeaderBackup() + public function testSessionHeaderBackup(): void { - $this->module->haveHttpHeader('foo', 'bar'); - $this->module->sendGET('/rest/foo/'); - $this->module->seeResponseContains('foo: "bar"'); + $this->rest->haveHttpHeader('foo', 'bar'); + $this->rest->sendGET('/rest/foo/'); + $this->rest->seeResponseContains('foo: "bar"'); $session = $this->phpBrowser->_backupSession(); - $this->module->haveHttpHeader('foo', 'baz'); - $this->module->sendGET('/rest/foo/'); - $this->module->seeResponseContains('foo: "baz"'); + $this->rest->haveHttpHeader('foo', 'baz'); + $this->rest->sendGET('/rest/foo/'); + $this->rest->seeResponseContains('foo: "baz"'); $this->phpBrowser->_loadSession($session); - $this->module->sendGET('/rest/foo/'); - $this->module->seeResponseContains('foo: "bar"'); + $this->rest->sendGET('/rest/foo/'); + $this->rest->seeResponseContains('foo: "bar"'); } - protected function shouldFail() + private function shouldFail(): void { $this->expectException(AssertionFailedError::class); } - public function testGrabFromCurrentUrl() + public function testGrabFromCurrentUrl(): void { - $this->module->sendGET('/rest/foo/'); + $this->rest->sendGET('/rest/foo/'); $this->assertEquals('/rest/foo/', $this->phpBrowser->grabFromCurrentUrl()); } } diff --git a/tests/unit/Codeception/Module/PhpBrowserTest.php b/tests/unit/Codeception/Module/PhpBrowserTest.php index 1d9e39d..aa48e79 100644 --- a/tests/unit/Codeception/Module/PhpBrowserTest.php +++ b/tests/unit/Codeception/Module/PhpBrowserTest.php @@ -11,7 +11,7 @@ use Codeception\Module\PhpBrowser; use Codeception\Stub; -require_once 'tests/data/app/data.php'; +require_once dirname(dirname(dirname(__DIR__))) . '/data/app/data.php'; require_once __DIR__ . '/TestsForBrowsers.php'; use Codeception\Test\Cept; @@ -26,9 +26,9 @@ final class PhpBrowserTest extends TestsForBrowsers { protected PhpBrowser $module; - protected array $history = []; + private array $history = []; - protected function _setUp() + protected function _setUp(): void { $container = Stub::make(ModuleContainer::class); $this->module = new PhpBrowser($container); @@ -37,7 +37,6 @@ protected function _setUp() $this->module->_initialize(); $this->module->_before($this->makeTest()); $this->module->guzzle->getConfig('handler')->push(GuzzleMiddleware::history($this->history)); - } private function getLastRequest() @@ -49,7 +48,7 @@ private function getLastRequest() return $this->history->getLastRequest(); } - protected function _tearDown() + protected function _tearDown(): void { if ($this->module) { $this->module->_after($this->makeTest()); @@ -61,12 +60,12 @@ protected function _tearDown() /** * @return \\Codeception\Test\Cept&\PHPUnit\Framework\MockObject\MockObject */ - protected function makeTest() + private function makeTest() { return Stub::makeEmpty(Cept::class); } - public function testAjax() + public function testAjax(): void { $this->module->amOnPage('/'); $this->module->sendAjaxGetRequest('/info'); @@ -78,32 +77,32 @@ public function testAjax() $this->assertEquals('author', $post['show']); } - public function testLinksWithNonLatin() + public function testLinksWithNonLatin(): void { $this->module->amOnPage('/info'); $this->module->seeLink('Ссылочка'); $this->module->click('Ссылочка'); } - public function testHtmlSnapshot() + public function testHtmlSnapshot(): void { $this->module->amOnPage('/'); - $testName="debugPhpBrowser"; + $testName = "debugPhpBrowser"; $this->module->makeHtmlSnapshot($testName); - $this->assertFileExists(CodeceptConfig::outputDir().'debug/'.$testName.'.html'); - @unlink(CodeceptConfig::outputDir().'debug/'.$testName.'.html'); + $this->assertFileExists(CodeceptConfig::outputDir() . 'debug/' . $testName . '.html'); + @unlink(CodeceptConfig::outputDir() . 'debug/' . $testName . '.html'); } /** * @see https://github.com/Codeception/Codeception/issues/4509 */ - public function testSeeTextAfterJSComparisionOperator() + public function testSeeTextAfterJSComparisionOperator(): void { $this->module->amOnPage('/info'); $this->module->see('Text behind JS comparision'); } - public function testSetMultipleCookies() + public function testSetMultipleCookies(): void { $this->module->amOnPage('/'); $cookie_name_1 = 'test_cookie'; @@ -131,7 +130,7 @@ public function testSetMultipleCookies() $this->module->dontSeeCookie($cookie_name_2); } - public function testSessionsHaveIndependentCookies() + public function testSessionsHaveIndependentCookies(): void { $this->module->amOnPage('/'); $cookie_name_1 = 'test_cookie'; @@ -153,7 +152,7 @@ public function testSessionsHaveIndependentCookies() $this->module->seeCookie($cookie_name_1); } - public function testSubmitFormGet() + public function testSubmitFormGet(): void { $I = $this->module; $I->amOnPage('/search'); @@ -161,7 +160,7 @@ public function testSubmitFormGet() $I->see('Success'); } - public function testHtmlRedirect() + public function testHtmlRedirect(): void { $this->module->amOnPage('/redirect2'); $this->module->seeResponseCodeIs(200); @@ -171,21 +170,21 @@ public function testHtmlRedirect() $this->module->seeCurrentUrlEquals('/redirect_interval'); } - public function testHtmlRedirectWithParams() + public function testHtmlRedirectWithParams(): void { $this->module->amOnPage('/redirect_params'); $this->module->seeResponseCodeIs(200); $this->module->seeCurrentUrlEquals('/search?one=1&two=2'); } - public function testMetaRefresh() + public function testMetaRefresh(): void { $this->module->amOnPage('/redirect_meta_refresh'); $this->module->seeResponseCodeIs(200); $this->module->seeCurrentUrlEquals('/info'); } - public function testMetaRefreshIsIgnoredIfIntervalIsLongerThanMaxInterval() + public function testMetaRefreshIsIgnoredIfIntervalIsLongerThanMaxInterval(): void { // prepare config $config = $this->module->_getConfig(); @@ -196,7 +195,7 @@ public function testMetaRefreshIsIgnoredIfIntervalIsLongerThanMaxInterval() $this->module->seeCurrentUrlEquals('/redirect_meta_refresh'); } - public function testRefreshRedirect() + public function testRefreshRedirect(): void { $this->module->amOnPage('/redirect3'); $this->module->seeResponseCodeIs(200); @@ -207,7 +206,7 @@ public function testRefreshRedirect() $this->module->see('Welcome to test app!'); } - public function testRedirectWithGetParams() + public function testRedirectWithGetParams(): void { $this->module->amOnPage('/redirect4'); $this->module->seeInCurrentUrl('/search?ln=test@gmail.com&sn=testnumber'); @@ -216,7 +215,7 @@ public function testRedirectWithGetParams() $this->assertContains('test@gmail.com', $params); } - public function testRedirectBaseUriHasPath() + public function testRedirectBaseUriHasPath(): void { // prepare config $config = $this->module->_getConfig(); @@ -229,7 +228,7 @@ public function testRedirectBaseUriHasPath() $this->module->see('Lots of valuable data here'); } - public function testRedirectBaseUriHasPathAnd302Code() + public function testRedirectBaseUriHasPathAnd302Code(): void { // prepare config $config = $this->module->_getConfig(); @@ -242,7 +241,7 @@ public function testRedirectBaseUriHasPathAnd302Code() $this->module->see('Lots of valuable data here'); } - public function testRelativeRedirect() + public function testRelativeRedirect(): void { // test relative redirects where the effective request URI is in a // subdirectory @@ -257,14 +256,14 @@ public function testRelativeRedirect() $this->module->seeCurrentUrlEquals('/info'); } - public function testChainedRedirects() + public function testChainedRedirects(): void { $this->module->amOnPage('/redirect_twice'); $this->module->seeResponseCodeIs(200); $this->module->seeCurrentUrlEquals('/info'); } - public function testDisabledRedirects() + public function testDisabledRedirects(): void { $this->module->client->followRedirects(false); $this->module->amOnPage('/redirect_twice'); @@ -272,22 +271,22 @@ public function testDisabledRedirects() $this->module->seeCurrentUrlEquals('/redirect_twice'); } - public function testRedirectLimitReached() + public function testRedirectLimitReached(): void { $this->module->client->setMaxRedirects(1); try { $this->module->amOnPage('/redirect_twice'); $this->fail('redirect limit is not respected'); - } catch (LogicException $exception) { + } catch (LogicException $logicException) { $this->assertEquals( 'The maximum number (1) of redirections was reached.', - $exception->getMessage(), + $logicException->getMessage(), 'redirect limit is respected' ); } } - public function testRedirectLimitNotReached() + public function testRedirectLimitNotReached(): void { $this->module->client->setMaxRedirects(2); $this->module->amOnPage('/redirect_twice'); @@ -295,14 +294,14 @@ public function testRedirectLimitNotReached() $this->module->seeCurrentUrlEquals('/info'); } - public function testLocationHeaderDoesNotRedirectWhenStatusCodeIs201() + public function testLocationHeaderDoesNotRedirectWhenStatusCodeIs201(): void { $this->module->amOnPage('/location_201'); $this->module->seeResponseCodeIs(201); $this->module->seeCurrentUrlEquals('/location_201'); } - public function testRedirectToAnotherDomainUsingSchemalessUrl() + public function testRedirectToAnotherDomainUsingSchemalessUrl(): void { $this->module->_reconfigure([ @@ -311,14 +310,13 @@ public function testRedirectToAnotherDomainUsingSchemalessUrl() new Response(200, [], 'Cool stuff') ]) ]); - /** @var GuzzleHandlerStack $handlerStack */ $this->module->amOnUrl('http://fictional.redirector/redirect-to?url=//example.org/'); $currentUrl = $this->module->client->getHistory()->current()->getUri(); $this->assertSame('http://example.org/', $currentUrl); } - public function testSetCookieByHeader() + public function testSetCookieByHeader(): void { $this->module->amOnPage('/cookies2'); $this->module->seeResponseCodeIs(200); @@ -327,14 +325,14 @@ public function testSetCookieByHeader() $this->module->seeCookie('c'); } - public function testSettingContentTypeFromHtml() + public function testSettingContentTypeFromHtml(): void { $this->module->amOnPage('/content-iso'); $charset = $this->module->client->getResponse()->getHeader('Content-Type'); $this->assertEquals('text/html;charset=ISO-8859-1', $charset); } - public function testSettingCharsetFromHtml() + public function testSettingCharsetFromHtml(): void { $this->module->amOnPage('/content-cp1251'); $charset = $this->module->client->getResponse()->getHeader('Content-Type'); @@ -344,7 +342,7 @@ public function testSettingCharsetFromHtml() /** * @Issue https://github.com/Codeception/Codeception/issues/933 */ - public function testSubmitFormWithQueries() + public function testSubmitFormWithQueries(): void { $this->module->amOnPage('/form/example3'); $this->module->seeElement('form'); @@ -356,14 +354,14 @@ public function testSubmitFormWithQueries() $this->module->seeCurrentUrlEquals('/form/example3?validate=yes'); } - public function testHeadersBySetHeader() + public function testHeadersBySetHeader(): void { $this->module->setHeader('xxx', 'yyyy'); $this->module->amOnPage('/'); $this->assertTrue($this->getLastRequest()->hasHeader('xxx')); } - public function testDeleteHeaders() + public function testDeleteHeaders(): void { $this->module->setHeader('xxx', 'yyyy'); $this->module->deleteHeader('xxx'); @@ -371,7 +369,7 @@ public function testDeleteHeaders() $this->assertFalse($this->getLastRequest()->hasHeader('xxx')); } - public function testDeleteHeadersByEmptyValue() + public function testDeleteHeadersByEmptyValue(): void { $this->module->setHeader('xxx', 'yyyy'); $this->module->setHeader('xxx', ''); @@ -379,7 +377,7 @@ public function testDeleteHeadersByEmptyValue() $this->assertFalse($this->getLastRequest()->hasHeader('xxx')); } - public function testCurlOptions() + public function testCurlOptions(): void { $this->module->_setConfig(['url' => 'http://google.com', 'curl' => ['CURLOPT_NOBODY' => true]]); $this->module->_initialize(); @@ -394,7 +392,7 @@ public function testCurlOptions() } - public function testCurlSslOptions() + public function testCurlSslOptions(): void { $this->module->_setConfig([ 'url' => 'https://github.com', @@ -412,7 +410,7 @@ public function testCurlSslOptions() $this->assertSame('', $this->module->_getResponseContent(), 'CURLOPT_NOBODY setting is not respected'); } - public function testHttpAuth() + public function testHttpAuth(): void { $this->module->amOnPage('/auth'); $this->module->seeResponseCodeIs(401); @@ -430,11 +428,11 @@ public function testHttpAuth() $this->module->see('Forbidden'); } - public function testRawGuzzle() + public function testRawGuzzle(): void { - $code = $this->module->executeInGuzzle(function (GuzzleClient $client): int { - $res = $client->get('/info'); - return $res->getStatusCode(); + $code = $this->module->executeInGuzzle(function (GuzzleClient $guzzleClient): int { + $response = $guzzleClient->get('/info'); + return $response->getStatusCode(); }); $this->assertEquals(200, $code); } @@ -459,7 +457,7 @@ public function testRawGuzzle() * this will check if current element contains inner arrays within it's keys * so we can ignore element itself and only process inner files */ - public function testFormWithFilesInOnlyArray() + public function testFormWithFilesInOnlyArray(): void { $this->shouldFail(); $this->module->amOnPage('/form/example13'); @@ -468,7 +466,7 @@ public function testFormWithFilesInOnlyArray() $this->module->click('Submit'); } - public function testDoubleSlash() + public function testDoubleSlash(): void { $I = $this->module; $I->amOnPage('/register'); @@ -479,13 +477,13 @@ public function testDoubleSlash() $this->assertEquals($formPath, '/register'); } - public function testFillFieldWithoutPage() + public function testFillFieldWithoutPage(): void { $this->expectException(ModuleException::class); $this->module->fillField('#name', 'Nothing special'); } - public function testArrayFieldSubmitForm() + public function testArrayFieldSubmitForm(): void { $this->module->amOnPage('/form/example17'); $this->module->submitForm( @@ -504,19 +502,19 @@ public function testArrayFieldSubmitForm() $this->assertEquals('crunked', $data['Food']['beer']['yum']['yeah']); } - public function testCookiesForDomain() + public function testCookiesForDomain(): void { - $mock = new MockHandler([ + $mockHandler = new MockHandler([ new Response(200, ['X-Foo' => 'Bar']), ]); - $handler = GuzzleHandlerStack::create($mock); - $handler->push(GuzzleMiddleware::history($this->history)); - - $client = new GuzzleClient(['handler' => $handler, 'base_uri' => 'https://codeception.com']); - $guzzleConnector = new Guzzle(); - $guzzleConnector->setClient($client); - $guzzleConnector->getCookieJar()->set(new Cookie('hello', 'world')); - $guzzleConnector->request('GET', 'https://codeception.com/'); + $guzzleHandlerStack = GuzzleHandlerStack::create($mockHandler); + $guzzleHandlerStack->push(GuzzleMiddleware::history($this->history)); + + $client = new GuzzleClient(['handler' => $guzzleHandlerStack, 'base_uri' => 'https://codeception.com']); + $guzzle = new Guzzle(); + $guzzle->setClient($client); + $guzzle->getCookieJar()->set(new Cookie('hello', 'world')); + $guzzle->request('GET', 'https://codeception.com/'); $this->assertArrayHasKey('cookies', $this->history[0]['options']); /** @var $cookie GuzzleHttp\Cookie\SetCookie **/ $cookies = $this->history[0]['options']['cookies']->toArray(); @@ -527,7 +525,7 @@ public function testCookiesForDomain() /** * @issue https://github.com/Codeception/Codeception/issues/2653 */ - public function testSetCookiesByOptions() + public function testSetCookiesByOptions(): void { $config = $this->module->_getConfig(); $config['cookies'] = [ @@ -549,7 +547,7 @@ public function testSetCookiesByOptions() /** * @issue https://github.com/Codeception/Codeception/issues/2234 */ - public function testEmptyValueOfCookie() + public function testEmptyValueOfCookie(): void { //set cookie $this->module->amOnPage('/cookies2'); @@ -559,7 +557,7 @@ public function testEmptyValueOfCookie() $this->module->dontSeeCookie('a'); } - public function testRequestApi() + public function testRequestApi(): void { $this->expectException(ModuleException::class); $response = $this->module->_request('POST', '/form/try', ['user' => 'davert']); @@ -570,7 +568,7 @@ public function testRequestApi() $this->module->click('Welcome to test app'); // page not loaded } - public function testLoadPageApi() + public function testLoadPageApi(): void { $this->module->_loadPage('POST', '/form/try', ['user' => 'davert']); $data = data::get('form'); @@ -583,7 +581,7 @@ public function testLoadPageApi() /** * @issue https://github.com/Codeception/Codeception/issues/2408 */ - public function testClickFailure() + public function testClickFailure(): void { $this->module->amOnPage('/info'); $this->expectException(ElementNotFound::class); @@ -594,7 +592,7 @@ public function testClickFailure() /** * @issue https://github.com/Codeception/Codeception/issues/2841 */ - public function testSubmitFormDoesNotKeepGetParameters() + public function testSubmitFormDoesNotKeepGetParameters(): void { $this->module->amOnPage('/form/bug2841?stuff=other'); $this->module->fillField('#texty', 'thingshjere'); @@ -602,7 +600,7 @@ public function testSubmitFormDoesNotKeepGetParameters() $this->assertEmpty(data::get('query'), 'Query string is not empty'); } - public function testClickLinkAndFillField() + public function testClickLinkAndFillField(): void { $this->module->amOnPage('/info'); $this->module->click('Sign in!'); @@ -610,21 +608,21 @@ public function testClickLinkAndFillField() $this->module->fillField('email', 'email@example.org'); } - public function testClickSelectsClickableElementFromMatches() + public function testClickSelectsClickableElementFromMatches(): void { $this->module->amOnPage('/form/multiple_matches'); $this->module->click('Press Me!'); $this->module->seeCurrentUrlEquals('/info'); } - public function testClickSelectsClickableElementFromMatchesUsingCssLocator() + public function testClickSelectsClickableElementFromMatchesUsingCssLocator(): void { $this->module->amOnPage('/form/multiple_matches'); $this->module->click(['css' => '.link']); $this->module->seeCurrentUrlEquals('/info'); } - public function testClickingOnButtonOutsideFormDoesNotCauseFatalError() + public function testClickingOnButtonOutsideFormDoesNotCauseFatalError(): void { $this->expectException(TestRuntimeException::class); $this->expectExceptionMessage('Button is not inside a link or a form'); @@ -632,7 +630,7 @@ public function testClickingOnButtonOutsideFormDoesNotCauseFatalError() $this->module->click('Submit 2'); } - public function testSubmitFormWithoutEmptyOptionsInSelect() + public function testSubmitFormWithoutEmptyOptionsInSelect(): void { $this->module->amOnPage('/form/bug3824'); $this->module->submitForm('form', []); @@ -642,7 +640,7 @@ public function testSubmitFormWithoutEmptyOptionsInSelect() /** * @issue https://github.com/Codeception/Codeception/issues/3953 */ - public function testFillFieldInGetFormWithoutId() + public function testFillFieldInGetFormWithoutId(): void { $this->module->amOnPage('/form/bug3953'); $this->module->selectOption('select_name', 'two'); @@ -654,18 +652,18 @@ public function testFillFieldInGetFormWithoutId() $this->assertEquals('searchterm', $params['search_name']); } - public function testGrabPageSourceWhenNotOnPage() + public function testGrabPageSourceWhenNotOnPage(): void { $this->expectException(ModuleException::class); $this->expectExceptionMessage('Page not loaded. Use `$I->amOnPage` (or hidden API methods `_request` and `_loadPage`) to open it'); $this->module->grabPageSource(); } - public function testGrabPageSourceWhenOnPage() + public function testGrabPageSourceWhenOnPage(): void { $this->module->amOnPage('/minimal'); $sourceExpected = -<< @@ -689,7 +687,7 @@ public function testGrabPageSourceWhenOnPage() /** * @issue https://github.com/Codeception/Codeception/issues/4383 */ - public function testSecondAmOnUrlWithEmptyPath() + public function testSecondAmOnUrlWithEmptyPath(): void { $this->module->amOnUrl('http://localhost:8000/info'); $this->module->see('Lots of valuable data here'); @@ -697,7 +695,7 @@ public function testSecondAmOnUrlWithEmptyPath() $this->module->dontSee('Lots of valuable data here'); } - public function testSetUserAgentUsingConfig() + public function testSetUserAgentUsingConfig(): void { $this->module->_setConfig(['headers' => ['User-Agent' => 'Codeception User Agent Test 1.0']]); $this->module->_initialize(); @@ -708,7 +706,7 @@ public function testSetUserAgentUsingConfig() $this->assertEquals('Codeception User Agent Test 1.0', $response, 'Incorrect user agent'); } - public function testIfStatusCodeIsWithin2xxRange() + public function testIfStatusCodeIsWithin2xxRange(): void { $this->module->amOnPage('https://httpstat.us/200'); $this->module->seeResponseCodeIsSuccessful(); @@ -717,7 +715,7 @@ public function testIfStatusCodeIsWithin2xxRange() $this->module->seeResponseCodeIsSuccessful(); } - public function testIfStatusCodeIsWithin3xxRange() + public function testIfStatusCodeIsWithin3xxRange(): void { $this->module->amOnPage('https://httpstat.us/300'); $this->module->seeResponseCodeIsRedirection(); @@ -726,7 +724,7 @@ public function testIfStatusCodeIsWithin3xxRange() $this->module->seeResponseCodeIsRedirection(); } - public function testIfStatusCodeIsWithin4xxRange() + public function testIfStatusCodeIsWithin4xxRange(): void { $this->module->amOnPage('https://httpstat.us/400'); $this->module->seeResponseCodeIsClientError(); @@ -735,7 +733,7 @@ public function testIfStatusCodeIsWithin4xxRange() $this->module->seeResponseCodeIsClientError(); } - public function testIfStatusCodeIsWithin5xxRange() + public function testIfStatusCodeIsWithin5xxRange(): void { $this->module->amOnPage('https://httpstat.us/500'); $this->module->seeResponseCodeIsServerError(); @@ -747,7 +745,7 @@ public function testIfStatusCodeIsWithin5xxRange() /** * @issue https://github.com/Codeception/Codeception/issues/5547 */ - public function testSelectOptionByTextWhenItHasNoValue() + public function testSelectOptionByTextWhenItHasNoValue(): void { $this->module->amOnPage('/form/bug5547'); $this->module->selectOption('#_payment_type', 'qwerty'); diff --git a/tests/unit/Codeception/Module/TestsForBrowsers.php b/tests/unit/Codeception/Module/TestsForBrowsers.php index 3edac74..e5ca192 100644 --- a/tests/unit/Codeception/Module/TestsForBrowsers.php +++ b/tests/unit/Codeception/Module/TestsForBrowsers.php @@ -4,7 +4,7 @@ use Codeception\Exception\ModuleException; -require_once 'TestsForWeb.php'; +require_once __DIR__ . '/TestsForWeb.php'; /** * Author: davert @@ -14,8 +14,7 @@ */ abstract class TestsForBrowsers extends TestsForWeb { - - public function testAmOnSubdomain() + public function testAmOnSubdomain(): void { $this->module->_reconfigure(['url' => 'https://google.com']); $this->module->amOnSubdomain('user'); @@ -26,7 +25,7 @@ public function testAmOnSubdomain() $this->assertEquals('https://user.google.com', $this->module->_getUrl()); } - public function testOpenAbsoluteUrls() + public function testOpenAbsoluteUrls(): void { $this->module->amOnUrl('http://localhost:8000/'); $this->module->see('Welcome to test app!', 'h1'); @@ -37,7 +36,7 @@ public function testOpenAbsoluteUrls() $this->assertEquals('http://127.0.0.1:8000', $this->module->_getUrl(), 'Host has changed'); } - public function testHeadersRedirect() + public function testHeadersRedirect(): void { $this->module->amOnPage('/redirect'); $this->module->seeInCurrentUrl('info'); @@ -46,7 +45,7 @@ public function testHeadersRedirect() /* * https://github.com/Codeception/Codeception/issues/1510 */ - public function testSiteRootRelativePathsForBasePathWithSubdir() + public function testSiteRootRelativePathsForBasePathWithSubdir(): void { $this->module->_reconfigure(['url' => 'http://localhost:8000/form']); $this->module->amOnPage('/relative_siteroot'); @@ -60,7 +59,7 @@ public function testSiteRootRelativePathsForBasePathWithSubdir() $this->module->dontSeeInCurrentUrl('form/form/'); } - public function testOpenPageException() + public function testOpenPageException(): void { $this->expectException(ModuleException::class); $this->module->see('Hello'); diff --git a/tests/unit/Codeception/Module/TestsForWeb.php b/tests/unit/Codeception/Module/TestsForWeb.php index a15e114..a07d202 100644 --- a/tests/unit/Codeception/Module/TestsForWeb.php +++ b/tests/unit/Codeception/Module/TestsForWeb.php @@ -19,7 +19,7 @@ abstract class TestsForWeb extends Unit { protected PhpBrowser $module; - public function testAmOnPage() + public function testAmOnPage(): void { $this->module->amOnPage('/'); $this->module->see('Welcome to test app!'); @@ -28,7 +28,7 @@ public function testAmOnPage() $this->module->see('Information'); } - public function testCurrentUrl() + public function testCurrentUrl(): void { $this->module->amOnPage('/info'); $this->module->seeCurrentUrlEquals('/info'); @@ -45,7 +45,7 @@ public function testCurrentUrl() } - public function testSee() + public function testSee(): void { $this->module->amOnPage('/'); $this->module->see('Welcome to test app!'); @@ -70,14 +70,14 @@ public function testSee() $this->module->dontSee('Welcome', 'h6'); } - public function testDontSeeFailsWhenMultilineTextMatches() + public function testDontSeeFailsWhenMultilineTextMatches(): void { $this->shouldFail(); $this->module->amOnPage('/'); $this->module->dontSee('Some text with formatting on separate lines'); } - public function testDontSeeFailsWhenMultilineTextMatchesInSelector() + public function testDontSeeFailsWhenMultilineTextMatchesInSelector(): void { $this->shouldFail(); $this->module->amOnPage('/'); @@ -87,21 +87,21 @@ public function testDontSeeFailsWhenMultilineTextMatchesInSelector() /** * @Issue https://github.com/Codeception/Codeception/issues/3114 */ - public function testSeeIsCaseInsensitiveForUnicodeText() + public function testSeeIsCaseInsensitiveForUnicodeText(): void { $this->module->amOnPage('/info'); $this->module->see('ссылочка'); $this->module->see('ссылочка', 'a'); } - public function testDontSeeIsCaseInsensitiveForUnicodeText() + public function testDontSeeIsCaseInsensitiveForUnicodeText(): void { $this->expectException(AssertionFailedError::class); $this->module->amOnPage('/info'); $this->module->dontSee('ссылочка'); } - public function testSeeInSource() + public function testSeeInSource(): void { $this->module->amOnPage('/'); $this->module->seeInSource('

Welcome to test app!

'); @@ -109,13 +109,13 @@ public function testSeeInSource() $this->module->dontSeeInSource('John Cleese'); } - public function testSeeInCurrentUrl() + public function testSeeInCurrentUrl(): void { $this->module->amOnPage('/info'); $this->module->seeInCurrentUrl('/info'); } - public function testSeeLink() + public function testSeeLink(): void { $this->module->amOnPage('/external_url'); $this->module->seeLink('Next'); @@ -124,14 +124,14 @@ public function testSeeLink() $this->module->dontSeeLink('Next', 'https://codeception'); } - public function testDontSeeLink() + public function testDontSeeLink(): void { $this->module->amOnPage('/external_url'); $this->module->dontSeeLink('Back'); $this->module->dontSeeLink('Next', '/fsdfsdf/'); } - public function testSeeLinkFailsIfTextDoesNotMatch() + public function testSeeLinkFailsIfTextDoesNotMatch(): void { $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage("No links containing text 'Codeception' were found in page /external_url"); @@ -139,7 +139,7 @@ public function testSeeLinkFailsIfTextDoesNotMatch() $this->module->seeLink('Codeception'); } - public function testSeeLinkFailsIfHrefDoesNotMatch() + public function testSeeLinkFailsIfHrefDoesNotMatch(): void { $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage("No links containing text 'Next' and URL '/fsdfsdf/' were found in page /external_url"); @@ -147,7 +147,7 @@ public function testSeeLinkFailsIfHrefDoesNotMatch() $this->module->seeLink('Next', '/fsdfsdf/'); } - public function testSeeLinkFailsIfHrefDoesNotMatchExactly() + public function testSeeLinkFailsIfHrefDoesNotMatchExactly(): void { $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage("No links containing text 'Next' and URL 'https://codeception' were found in page /external_url"); @@ -155,7 +155,7 @@ public function testSeeLinkFailsIfHrefDoesNotMatchExactly() $this->module->seeLink('Next', 'https://codeception'); } - public function testDontSeeLinkFailsIfTextMatches() + public function testDontSeeLinkFailsIfTextMatches(): void { $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage("Link containing text 'Next' was found in page /external_url"); @@ -163,7 +163,7 @@ public function testDontSeeLinkFailsIfTextMatches() $this->module->dontSeeLink('Next'); } - public function testDontSeeLinkFailsIfTextAndUrlMatches() + public function testDontSeeLinkFailsIfTextAndUrlMatches(): void { $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage("Link containing text 'Next' and URL 'https://codeception.com/' was found in page /external_url"); @@ -171,14 +171,14 @@ public function testDontSeeLinkFailsIfTextAndUrlMatches() $this->module->dontSeeLink('Next', 'https://codeception.com/'); } - public function testSeeLinkMatchesRelativeLink() + public function testSeeLinkMatchesRelativeLink(): void { $this->module->amOnPage('/info'); $this->module->seeLink('Sign in!', '/login'); $this->module->dontSeeLink('Sign in!', '/log'); } - public function testDontSeeLinkMatchesRelativeLink() + public function testDontSeeLinkMatchesRelativeLink(): void { $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage("Link containing text 'Sign in!' and URL '/login' was found in page /info"); @@ -186,7 +186,7 @@ public function testDontSeeLinkMatchesRelativeLink() $this->module->dontSeeLink('Sign in!', '/login'); } - public function testClick() + public function testClick(): void { $this->module->amOnPage('/'); $this->module->click('More info'); @@ -201,7 +201,7 @@ public function testClick() $this->module->seeInCurrentUrl('/info'); } - public function testClickByName() + public function testClickByName(): void { $this->module->amOnPage('/form/button'); $this->module->click("btn0"); @@ -210,14 +210,14 @@ public function testClickByName() $this->assertEquals('val', $form['text']); } - public function testClickByLinkTitle() + public function testClickByLinkTitle(): void { $this->module->amOnPage('/'); $this->module->click("Link Title"); $this->module->seeInCurrentUrl('/info'); } - public function testClickOnContext() + public function testClickOnContext(): void { $this->module->amOnPage('/'); $this->module->click('More info', 'p'); @@ -228,7 +228,7 @@ public function testClickOnContext() $this->module->seeInCurrentUrl('/info'); } - public function testCheckboxByCss() + public function testCheckboxByCss(): void { $this->module->amOnPage('/form/checkbox'); $this->module->checkOption('#checkin'); @@ -238,7 +238,7 @@ public function testCheckboxByCss() $this->assertEquals('agree', $form['terms']); } - public function testCheckboxByName() + public function testCheckboxByName(): void { $this->module->amOnPage('/form/checkbox'); $this->module->checkOption('terms'); @@ -248,7 +248,7 @@ public function testCheckboxByName() $this->assertEquals('agree', $form['terms']); } - public function testCheckboxByLabel() + public function testCheckboxByLabel(): void { $this->module->amOnPage('/form/checkbox'); $this->module->checkOption('I Agree'); @@ -262,7 +262,7 @@ public function testCheckboxByLabel() * @group testCheckboxArray * @Issue https://github.com/Codeception/Codeception/pull/1145 */ - public function testCheckboxArray() + public function testCheckboxArray(): void { $this->module->amOnPage('/form/checkbox_array'); $this->module->checkOption('#id2'); @@ -272,7 +272,7 @@ public function testCheckboxArray() $this->assertEquals('second', reset($form['field'])); } - public function testSelectByCss() + public function testSelectByCss(): void { $this->module->amOnPage('/form/select'); $this->module->selectOption('form select[name=age]', 'adult'); @@ -282,7 +282,7 @@ public function testSelectByCss() $this->assertEquals('adult', $form['age']); } - public function testSelectByName() + public function testSelectByName(): void { $this->module->amOnPage('/form/select'); $this->module->selectOption('age', 'adult'); @@ -292,7 +292,7 @@ public function testSelectByName() $this->assertEquals('adult', $form['age']); } - public function testSelectByLabel() + public function testSelectByLabel(): void { $this->module->amOnPage('/form/select'); $this->module->selectOption('Select your age', 'dead'); @@ -302,7 +302,7 @@ public function testSelectByLabel() $this->assertEquals('dead', $form['age']); } - public function testSelectByLabelAndOptionText() + public function testSelectByLabelAndOptionText(): void { $this->module->amOnPage('/form/select'); $this->module->selectOption('Select your age', '21-60'); @@ -312,14 +312,14 @@ public function testSelectByLabelAndOptionText() $this->assertEquals('adult', $form['age']); } - public function testSeeSelectedOption() + public function testSeeSelectedOption(): void { $this->module->amOnPage('/form/select'); $this->module->seeOptionIsSelected('#age', '60-100'); $this->module->dontSeeOptionIsSelected('#age', '100-210'); } - public function testSeeSelectedOptionForRadioButton() + public function testSeeSelectedOptionForRadioButton(): void { $this->module->amOnPage('/form/example6'); $this->module->seeOptionIsSelected('input[name=frequency]', 'hour'); @@ -329,7 +329,7 @@ public function testSeeSelectedOptionForRadioButton() /** * @Issue https://github.com/Codeception/Codeception/issues/2733 */ - public function testSeeSelectedOptionReturnsFirstOptionIfNotSelected() + public function testSeeSelectedOptionReturnsFirstOptionIfNotSelected(): void { $this->module->amOnPage('/form/complex'); $this->module->seeOptionIsSelected('#age', 'below 13'); @@ -343,7 +343,7 @@ public function testSeeSelectedOptionReturnsFirstOptionIfNotSelected() * @group testSubmitSeveralSubmitsForm * @Issue https://github.com/Codeception/Codeception/issues/1183 */ - public function testSubmitSeveralSubmitsForm() + public function testSubmitSeveralSubmitsForm(): void { $this->module->amOnPage('/form/example8'); $this->module->click('form button[value="second"]'); @@ -358,7 +358,7 @@ public function testSubmitSeveralSubmitsForm() * @group testSubmitSeveralSubmitsForm * @Issue https://github.com/Codeception/Codeception/issues/1183 */ - public function testSubmitLotsOfSubmitsForm() + public function testSubmitLotsOfSubmitsForm(): void { $this->module->amOnPage('/form/example11'); $this->module->click('form button[value="fifth"]'); @@ -367,7 +367,7 @@ public function testSubmitLotsOfSubmitsForm() $this->assertEquals('fifth', $form['submit']); } - public function testSelectMultipleOptionsByText() + public function testSelectMultipleOptionsByText(): void { $this->module->amOnPage('/form/select_multiple'); $this->module->selectOption('What do you like the most?', ['Play Video Games', 'Have Sex']); @@ -377,7 +377,7 @@ public function testSelectMultipleOptionsByText() $this->assertEquals(['play', 'adult'], $form['like']); } - public function testSelectMultipleOptionsByValue() + public function testSelectMultipleOptionsByValue(): void { $this->module->amOnPage('/form/select_multiple'); $this->module->selectOption('What do you like the most?', ['eat', 'adult']); @@ -387,7 +387,7 @@ public function testSelectMultipleOptionsByValue() $this->assertEquals(['eat', 'adult'], $form['like']); } - public function testHidden() + public function testHidden(): void { $this->module->amOnPage('/form/hidden'); $this->module->click('Submit'); @@ -396,7 +396,7 @@ public function testHidden() $this->assertEquals('kill_people', $form['action']); } - public function testTextareaByCss() + public function testTextareaByCss(): void { $this->module->amOnPage('/form/textarea'); $this->module->fillField('textarea', 'Nothing special'); @@ -406,7 +406,7 @@ public function testTextareaByCss() $this->assertEquals('Nothing special', $form['description']); } - public function testTextareaByLabel() + public function testTextareaByLabel(): void { $this->module->amOnPage('/form/textarea'); $this->module->fillField('Description', 'Nothing special'); @@ -416,7 +416,7 @@ public function testTextareaByLabel() $this->assertEquals('Nothing special', $form['description']); } - public function testTextFieldByCss() + public function testTextFieldByCss(): void { $this->module->amOnPage('/form/field'); $this->module->fillField('#name', 'Nothing special'); @@ -426,7 +426,7 @@ public function testTextFieldByCss() $this->assertEquals('Nothing special', $form['name']); } - public function testTextFieldByName() + public function testTextFieldByName(): void { $this->module->amOnPage('/form/example1'); $this->module->fillField('LoginForm[username]', 'davert'); @@ -438,7 +438,7 @@ public function testTextFieldByName() $this->assertEquals('123456', $login['LoginForm']['password']); } - public function testTextFieldByLabel() + public function testTextFieldByLabel(): void { $this->module->amOnPage('/form/field'); $this->module->fillField('Name', 'Nothing special'); @@ -448,7 +448,7 @@ public function testTextFieldByLabel() $this->assertEquals('Nothing special', $form['name']); } - public function testTextFieldByLabelWithoutFor() + public function testTextFieldByLabelWithoutFor(): void { $this->module->amOnPage('/form/field'); $this->module->fillField('Other label', 'Nothing special'); @@ -458,7 +458,7 @@ public function testTextFieldByLabelWithoutFor() $this->assertEquals('Nothing special', $form['othername']); } - public function testFileFieldByCss() + public function testFileFieldByCss(): void { $this->module->amOnPage('/form/file'); $this->module->attachFile('#avatar', 'app/avatar.jpg'); @@ -468,7 +468,7 @@ public function testFileFieldByCss() $this->assertArrayHasKey('avatar', $files); } - public function testFileFieldByLabel() + public function testFileFieldByLabel(): void { $this->module->amOnPage('/form/file'); $this->module->attachFile('Avatar', 'app/avatar.jpg'); @@ -476,33 +476,33 @@ public function testFileFieldByLabel() $this->assertNotEmpty(data::get('files')); } - public function testSeeCheckboxIsNotChecked() + public function testSeeCheckboxIsNotChecked(): void { $this->module->amOnPage('/form/checkbox'); $this->module->dontSeeCheckboxIsChecked('#checkin'); $this->module->dontSeeCheckboxIsChecked('I Agree'); } - public function testSeeCheckboxChecked() + public function testSeeCheckboxChecked(): void { $this->module->amOnPage('/info'); $this->module->seeCheckboxIsChecked('input[type=checkbox]'); $this->module->seeCheckboxIsChecked('Checked'); } - public function testSeeWithNonLatin() + public function testSeeWithNonLatin(): void { $this->module->amOnPage('/info'); $this->module->see('на'); } - public function testSeeWithNonLatinAndSelectors() + public function testSeeWithNonLatinAndSelectors(): void { $this->module->amOnPage('/info'); $this->module->see('Текст', 'p'); } - public function testSeeInFieldOnInput() + public function testSeeInFieldOnInput(): void { $this->module->amOnPage('/form/field'); $this->module->seeInField('Name', 'OLD_VALUE'); @@ -510,13 +510,13 @@ public function testSeeInFieldOnInput() $this->module->seeInField('descendant-or-self::input[@id="name"]', 'OLD_VALUE'); } - public function testSeeInFieldForEmptyInput() + public function testSeeInFieldForEmptyInput(): void { $this->module->amOnPage('/form/empty'); $this->module->seeInField('#empty_input', ''); } - public function testSeeInFieldOnTextarea() + public function testSeeInFieldOnTextarea(): void { $this->module->amOnPage('/form/textarea'); $this->module->seeInField('Description', 'sunrise'); @@ -524,13 +524,13 @@ public function testSeeInFieldOnTextarea() $this->module->seeInField('descendant-or-self::textarea[@id="description"]', 'sunrise'); } - public function testSeeInFieldForEmptyTextarea() + public function testSeeInFieldForEmptyTextarea(): void { $this->module->amOnPage('/form/empty'); $this->module->seeInField('#empty_textarea', ''); } - public function testSeeInFieldOnCheckbox() + public function testSeeInFieldOnCheckbox(): void { $this->module->amOnPage('/form/field_values'); $this->module->dontSeeInField('checkbox[]', 'not seen one'); @@ -541,7 +541,7 @@ public function testSeeInFieldOnCheckbox() $this->module->seeInField('checkbox[]', 'see test three'); } - public function testSeeInFieldWithBoolean() + public function testSeeInFieldWithBoolean(): void { $this->module->amOnPage('/form/field_values'); $this->module->seeInField('checkbox1', true); @@ -554,7 +554,7 @@ public function testSeeInFieldWithBoolean() $this->module->dontSeeInField('radio3', true); } - public function testSeeInFieldOnRadio() + public function testSeeInFieldOnRadio(): void { $this->module->amOnPage('/form/field_values'); $this->module->seeInField('radio1', 'see test one'); @@ -563,7 +563,7 @@ public function testSeeInFieldOnRadio() $this->module->dontSeeInField('radio1', 'not seen three'); } - public function testSeeInFieldOnSelect() + public function testSeeInFieldOnSelect(): void { $this->module->amOnPage('/form/field_values'); $this->module->seeInField('select1', 'see test one'); @@ -574,13 +574,13 @@ public function testSeeInFieldOnSelect() $this->module->dontSeeInField('select1', 'Not selected'); } - public function testSeeInFieldEmptyValueForUnselectedSelect() + public function testSeeInFieldEmptyValueForUnselectedSelect(): void { $this->module->amOnPage('/form/field_values'); $this->module->seeInField('select3', ''); } - public function testSeeInFieldOnSelectMultiple() + public function testSeeInFieldOnSelectMultiple(): void { $this->module->amOnPage('/form/field_values'); $this->module->dontSeeInField('select2', 'not seen one'); @@ -591,13 +591,13 @@ public function testSeeInFieldOnSelectMultiple() $this->module->seeInField('select2', 'see test three'); } - public function testSeeInFieldWithExactMatch() + public function testSeeInFieldWithExactMatch(): void { $this->module->amOnPage('/form/field_values'); $this->module->seeInField(['name' => 'select2'], 'see test one'); } - public function testDontSeeInFieldOnInput() + public function testDontSeeInFieldOnInput(): void { $this->module->amOnPage('/form/field'); $this->module->dontSeeInField('Name', 'Davert'); @@ -605,7 +605,7 @@ public function testDontSeeInFieldOnInput() $this->module->dontSeeInField('descendant-or-self::input[@id="name"]', 'Davert'); } - public function testDontSeeInFieldOnTextarea() + public function testDontSeeInFieldOnTextarea(): void { $this->module->amOnPage('/form/textarea'); $this->module->dontSeeInField('Description', 'sunset'); @@ -613,7 +613,7 @@ public function testDontSeeInFieldOnTextarea() $this->module->dontSeeInField('descendant-or-self::textarea[@id="description"]', 'sunset'); } - public function testSeeInFormFields() + public function testSeeInFormFields(): void { $this->module->amOnPage('/form/field_values'); $params = [ @@ -634,7 +634,7 @@ public function testSeeInFormFields() $this->module->seeInFormFields('form', $params); } - public function testSeeInFormFieldsFails() + public function testSeeInFormFieldsFails(): void { $this->module->amOnPage('/form/field_values'); $this->expectException(AssertionFailedError::class); @@ -652,7 +652,7 @@ public function testSeeInFormFieldsFails() $this->module->seeInFormFields('form', $params); } - public function testDontSeeInFormFields() + public function testDontSeeInFormFields(): void { $this->module->amOnPage('/form/field_values'); $params = [ @@ -672,7 +672,7 @@ public function testDontSeeInFormFields() $this->module->dontSeeInFormFields('form', $params); } - public function testDontSeeInFormFieldsFails() + public function testDontSeeInFormFieldsFails(): void { $this->module->amOnPage('/form/field_values'); $this->expectException(AssertionFailedError::class); @@ -689,7 +689,7 @@ public function testDontSeeInFormFieldsFails() $this->module->dontSeeInFormFields('form', $params); } - public function testSeeInFormFieldsWithAssociativeArrays() + public function testSeeInFormFieldsWithAssociativeArrays(): void { $this->module->amOnPage('/form/example17'); $this->module->seeInFormFields('form', [ @@ -698,20 +698,20 @@ public function testSeeInFormFieldsWithAssociativeArrays() ]); } - public function testSeeInFieldWithNonLatin() + public function testSeeInFieldWithNonLatin(): void { $this->module->amOnPage('/info'); $this->module->seeInField('rus', 'Верно'); } - public function testApostrophesInText() + public function testApostrophesInText(): void { $this->module->amOnPage('/info'); $this->module->see("Don't do that at home!"); $this->module->see("Don't do that at home!", 'h3'); } - public function testSign() + public function testSign(): void { $this->module->amOnPage('/info'); $this->module->seeLink('Sign in!'); @@ -719,7 +719,7 @@ public function testSign() $this->module->click('Sign in!'); } - public function testGrabTextFrom() + public function testGrabTextFrom(): void { $this->module->amOnPage('/'); $result = $this->module->grabTextFrom('h1'); @@ -730,7 +730,7 @@ public function testGrabTextFrom() $this->assertEquals('test', $result); } - public function testGrabValueFrom() + public function testGrabValueFrom(): void { $this->module->amOnPage('/form/hidden'); $result = $this->module->grabValueFrom('#action'); @@ -748,7 +748,7 @@ public function testGrabValueFrom() /** * @see https://github.com/Codeception/Codeception/issues/3866 */ - public function testGrabValueFromWithFillField() + public function testGrabValueFromWithFillField(): void { $this->module->amOnPage('/form/bug3866'); $this->module->fillField('empty', 'new value'); @@ -763,13 +763,13 @@ public function testGrabValueFromWithFillField() $this->assertEquals('new value', $result); } - public function testGrabAttributeFrom() + public function testGrabAttributeFrom(): void { $this->module->amOnPage('/search'); $this->assertEquals('get', $this->module->grabAttributeFrom('form', 'method')); } - public function testLinksWithSimilarNames() + public function testLinksWithSimilarNames(): void { $this->module->amOnPage('/'); $this->module->click('Test Link'); @@ -779,7 +779,7 @@ public function testLinksWithSimilarNames() $this->module->seeInCurrentUrl('/form/hidden'); } - public function testLinksWithDifferentContext() + public function testLinksWithDifferentContext(): void { $this->module->amOnPage('/'); $this->module->click('Test', '#area1'); @@ -789,7 +789,7 @@ public function testLinksWithDifferentContext() $this->module->seeInCurrentUrl('/form/hidden'); } - public function testSeeElementOnPage() + public function testSeeElementOnPage(): void { $this->module->amOnPage('/form/field'); $this->module->seeElement('input[name=name]'); @@ -802,14 +802,14 @@ public function testSeeElementOnPage() } // regression test. https://github.com/Codeception/Codeception/issues/587 - public function testSeeElementOnPageFails() + public function testSeeElementOnPageFails(): void { $this->expectException(AssertionFailedError::class); $this->module->amOnPage('/form/field'); $this->module->dontSeeElement('input[name=name]'); } - public function testCookies() + public function testCookies(): void { $cookie_name = 'test_cookie'; $cookie_value = 'this is a test'; @@ -828,7 +828,7 @@ public function testCookies() $this->module->dontSeeCookie($cookie_name); } - public function testCookiesWithPath() + public function testCookiesWithPath(): void { $cookie_name = 'cookie'; $cookie_value = 'tasty'; @@ -846,7 +846,7 @@ public function testCookiesWithPath() $this->module->dontSeeCookie($cookie_name); } - public function testSendingCookies() + public function testSendingCookies(): void { $this->module->amOnPage('/'); $this->module->setCookie('nocookie', '1111'); @@ -854,7 +854,7 @@ public function testSendingCookies() $this->module->see('nocookie', 'pre'); } - public function testPageTitle() + public function testPageTitle(): void { $this->module->amOnPage('/'); $this->module->seeInTitle('TestEd Beta 2.0'); @@ -864,77 +864,77 @@ public function testPageTitle() $this->module->dontSeeInTitle('TestEd Beta 2.0'); } - public function testSeeFails() + public function testSeeFails(): void { $this->shouldFail(); $this->module->amOnPage('/'); $this->module->see('Text not here'); } - public function testSeeInsideFails() + public function testSeeInsideFails(): void { $this->shouldFail(); $this->module->amOnPage('/info'); $this->module->see('woups', 'p'); } - public function testDontSeeInInsideFails() + public function testDontSeeInInsideFails(): void { $this->shouldFail(); $this->module->amOnPage('/info'); $this->module->dontSee('interesting', 'p'); } - public function testSeeElementFails() + public function testSeeElementFails(): void { $this->shouldFail(); $this->module->amOnPage('/info'); $this->module->seeElement('.alert'); } - public function testDontSeeElementFails() + public function testDontSeeElementFails(): void { $this->shouldFail(); $this->module->amOnPage('/info'); $this->module->dontSeeElement('#back'); } - public function testSeeInFieldFail() + public function testSeeInFieldFail(): void { $this->shouldFail(); $this->module->amOnPage('/form/empty'); $this->module->seeInField('#empty_textarea', 'xxx'); } - public function testSeeInFieldOnTextareaFails() + public function testSeeInFieldOnTextareaFails(): void { $this->shouldFail(); $this->module->amOnPage('/form/textarea'); $this->module->dontSeeInField('Description', 'sunrise'); } - public function testSeeCheckboxIsNotCheckedFails() + public function testSeeCheckboxIsNotCheckedFails(): void { $this->shouldFail(); $this->module->amOnPage('/form/complex'); $this->module->dontSeeCheckboxIsChecked('#checkin'); } - public function testSeeCheckboxCheckedFails() + public function testSeeCheckboxCheckedFails(): void { $this->shouldFail(); $this->module->amOnPage('/form/checkbox'); $this->module->seeCheckboxIsChecked('#checkin'); } - public function testDontSeeElementOnPageFails() + public function testDontSeeElementOnPageFails(): void { $this->shouldFail(); $this->module->amOnPage('/form/field'); $this->module->dontSeeElement('descendant-or-self::input[@id="name"]'); } - public function testStrictLocators() + public function testStrictLocators(): void { $this->module->amOnPage('/login'); $this->module->seeElement(['id' => 'submit-label']); @@ -953,14 +953,14 @@ public function testStrictLocators() $this->module->seeCurrentUrlEquals('/form/hidden'); } - public function testFailStrictLocators() + public function testFailStrictLocators(): void { $this->shouldFail(); $this->module->amOnPage('/form/checkbox'); $this->module->checkOption(['name' => 'age']); } - public function testExample1() + public function testExample1(): void { $this->module->amOnPage('/form/example1'); $this->module->see('Login', 'button'); @@ -975,7 +975,7 @@ public function testExample1() $this->assertNotEmpty($login['LoginForm']['rememberMe']); } - public function testExample2() + public function testExample2(): void { $this->module->amOnPage('/form/example2'); $this->module->fillField('input[name=username]', 'davert'); @@ -988,7 +988,7 @@ public function testExample2() $this->assertEquals('login', $login['action']); } - public function testAmpersand() + public function testAmpersand(): void { $this->module->amOnPage('/info'); $this->module->see('Kill & Destroy'); @@ -998,7 +998,7 @@ public function testAmpersand() /** * https://github.com/Codeception/Codeception/issues/1091 */ - public function testExample4() + public function testExample4(): void { $this->module->amOnPage('/form/example4'); $this->module->click(['css' => '#register button[type="submit"]']); @@ -1010,7 +1010,7 @@ public function testExample4() /** * https://github.com/Codeception/Codeception/issues/1098 */ - public function testExample5() + public function testExample5(): void { $this->module->amOnPage('/form/example5'); $this->module->fillField('username', 'John'); @@ -1019,14 +1019,14 @@ public function testExample5() $this->module->seeCurrentUrlEquals('/form/example5?username=John&password=1234'); } - public function testExample5WithSubmitForm() + public function testExample5WithSubmitForm(): void { $this->module->amOnPage('/form/example5'); $this->module->submitForm('form', ['username' => 'John', 'password' => '1234']); $this->module->seeCurrentUrlEquals('/form/example5?username=John&password=1234'); } - public function testExample5WithParams() + public function testExample5WithParams(): void { $this->module->amOnPage('/form/example5?a=b'); $this->module->fillField('username', 'John'); @@ -1035,7 +1035,7 @@ public function testExample5WithParams() $this->module->seeCurrentUrlEquals('/form/example5?username=John&password=1234'); } - public function testExample5WithSubmitFormAndParams() + public function testExample5WithSubmitFormAndParams(): void { $this->module->amOnPage('/form/example5?a=b'); $this->module->submitForm('form', ['username' => 'John', 'password' => '1234']); @@ -1045,7 +1045,7 @@ public function testExample5WithSubmitFormAndParams() /** * @Issue https://github.com/Codeception/Codeception/issues/1212 */ - public function testExample9() + public function testExample9(): void { $this->module->amOnPage('/form/example9'); $this->module->attachFile('form[name=package_csv_form] input[name=xls_file]', 'app/avatar.jpg'); @@ -1060,7 +1060,7 @@ public function testExample9() $this->assertArrayHasKey('form_name', $form); } - public function testSubmitForm() + public function testSubmitForm(): void { $this->module->amOnPage('/form/complex'); $this->module->submitForm('form', [ @@ -1077,7 +1077,7 @@ public function testSubmitForm() $this->assertEquals('kill_all', $form['action']); } - public function testSubmitFormWithFillField() + public function testSubmitFormWithFillField(): void { $this->module->amOnPage('/form/complex'); $this->module->fillField('name', 'Kilgore Trout'); @@ -1090,7 +1090,7 @@ public function testSubmitFormWithFillField() $this->assertEquals('Is from Iliyum, NY', $form['description']); } - public function testSubmitFormWithoutButton() + public function testSubmitFormWithoutButton(): void { $this->module->amOnPage('/form/empty'); $this->module->submitForm('form', [ @@ -1100,7 +1100,7 @@ public function testSubmitFormWithoutButton() $this->assertEquals('Hello!', $form['text']); } - public function testSubmitFormWithAmpersand() + public function testSubmitFormWithAmpersand(): void { $this->module->amOnPage('/form/submitform_ampersands'); $this->module->submitForm('form', []); @@ -1109,7 +1109,7 @@ public function testSubmitFormWithAmpersand() $this->assertEquals('this & that', $form['test']); } - public function testSubmitFormWithArrayField() + public function testSubmitFormWithArrayField(): void { $this->module->amOnPage('/form/example17'); $this->module->submitForm('form', []); @@ -1119,7 +1119,7 @@ public function testSubmitFormWithArrayField() $this->assertArrayNotHasKey('FooBar[bar]', $data); } - public function testSubmitFormMultiSelectWithArrayParameter() + public function testSubmitFormMultiSelectWithArrayParameter(): void { $this->module->amOnPage('/form/submitform_multiple'); $this->module->submitForm('form', [ @@ -1134,7 +1134,7 @@ public function testSubmitFormMultiSelectWithArrayParameter() $this->assertEquals('not seen four', $form['select'][1]); } - public function testSubmitFormWithMultiSelect() + public function testSubmitFormWithMultiSelect(): void { $this->module->amOnPage('/form/submitform_multiple'); $this->module->submitForm('form', []); @@ -1145,7 +1145,7 @@ public function testSubmitFormWithMultiSelect() $this->assertEquals('see test two', $form['select'][1]); } - public function testSubmitFormCheckboxWithArrayParameter() + public function testSubmitFormCheckboxWithArrayParameter(): void { $this->module->amOnPage('/form/field_values'); $this->module->submitForm('form', [ @@ -1162,7 +1162,7 @@ public function testSubmitFormCheckboxWithArrayParameter() $this->assertEquals('not seen three', $form['checkbox'][2]); } - public function testSubmitFormCheckboxWithBooleanArrayParameter() + public function testSubmitFormCheckboxWithBooleanArrayParameter(): void { $this->module->amOnPage('/form/field_values'); $this->module->submitForm('form', [ @@ -1181,13 +1181,13 @@ public function testSubmitFormCheckboxWithBooleanArrayParameter() /** * https://github.com/Codeception/Codeception/issues/1381 */ - public function testFillingFormFieldWithoutSubmitButton() + public function testFillingFormFieldWithoutSubmitButton(): void { $this->module->amOnPage('/form/empty_fill'); $this->module->fillField('test', 'value'); } - public function testSubmitFormWithDefaultTextareaValue() + public function testSubmitFormWithDefaultTextareaValue(): void { $this->module->amOnPage('/form/textarea'); $this->module->submitForm('form', []); @@ -1199,7 +1199,7 @@ public function testSubmitFormWithDefaultTextareaValue() /** * @issue #1180 */ - public function testClickLinkWithInnerSpan() + public function testClickLinkWithInnerSpan(): void { $this->module->amOnPage('/form/example7'); $this->module->click("Buy Chocolate Bar"); @@ -1209,7 +1209,7 @@ public function testClickLinkWithInnerSpan() /* * @issue #1304 */ - public function testSelectTwoSubmitsByText() + public function testSelectTwoSubmitsByText(): void { $this->module->amOnPage('/form/select_two_submits'); $this->module->selectOption('What kind of sandwich would you like?', '2'); @@ -1219,7 +1219,7 @@ public function testSelectTwoSubmitsByText() $this->assertEquals(2, $form['sandwich_select']); } - public function testSelectTwoSubmitsByCSS() + public function testSelectTwoSubmitsByCSS(): void { $this->module->amOnPage('/form/select_two_submits'); $this->module->selectOption("form select[name='sandwich_select']", '2'); @@ -1237,7 +1237,7 @@ protected function shouldFail() /** * https://github.com/Codeception/Codeception/issues/1051 */ - public function testSubmitFormWithTwoSubmitButtonsSubmitsCorrectValue() + public function testSubmitFormWithTwoSubmitButtonsSubmitsCorrectValue(): void { $this->module->amOnPage('/form/example10'); $this->module->seeElement("#button2"); @@ -1253,7 +1253,7 @@ public function testSubmitFormWithTwoSubmitButtonsSubmitsCorrectValue() /** * https://github.com/Codeception/Codeception/issues/1051 */ - public function testSubmitFormWithTwoSubmitButtonsSubmitsCorrectValueAfterFillField() + public function testSubmitFormWithTwoSubmitButtonsSubmitsCorrectValueAfterFillField(): void { $this->module->amOnPage('/form/example10'); $this->module->fillField("username", "bob"); @@ -1269,7 +1269,7 @@ public function testSubmitFormWithTwoSubmitButtonsSubmitsCorrectValueAfterFillFi /* * https://github.com/Codeception/Codeception/issues/1274 */ - public function testSubmitFormWithDocRelativePathForAction() + public function testSubmitFormWithDocRelativePathForAction(): void { $this->module->amOnPage('/form/example12'); $this->module->submitForm('form', [ @@ -1278,7 +1278,7 @@ public function testSubmitFormWithDocRelativePathForAction() $this->module->seeCurrentUrlEquals('/form/example11'); } - public function testSubmitFormWithDocRelativePathForActionFromDefaultPage() + public function testSubmitFormWithDocRelativePathForActionFromDefaultPage(): void { $this->module->amOnPage('/form/'); $this->module->submitForm('form', [ @@ -1287,7 +1287,7 @@ public function testSubmitFormWithDocRelativePathForActionFromDefaultPage() $this->module->seeCurrentUrlEquals('/form/example11'); } - public function testLinkWithDocRelativeURLFromDefaultPage() + public function testLinkWithDocRelativeURLFromDefaultPage(): void { $this->module->amOnPage('/form/'); $this->module->click('Doc-Relative Link'); @@ -1297,7 +1297,7 @@ public function testLinkWithDocRelativeURLFromDefaultPage() /* * https://github.com/Codeception/Codeception/issues/1507 */ - public function testSubmitFormWithDefaultRadioAndCheckboxValues() + public function testSubmitFormWithDefaultRadioAndCheckboxValues(): void { $this->module->amOnPage('/form/example16'); $this->module->submitForm('form', [ @@ -1310,7 +1310,7 @@ public function testSubmitFormWithDefaultRadioAndCheckboxValues() $this->assertEquals('to be sent', $form['radio1']); } - public function testSubmitFormCheckboxWithBoolean() + public function testSubmitFormCheckboxWithBoolean(): void { $this->module->amOnPage('/form/example16'); $this->module->submitForm('form', [ @@ -1328,14 +1328,14 @@ public function testSubmitFormCheckboxWithBoolean() $this->assertArrayNotHasKey('checkbox1', $form, 'Checkbox value sent'); } - public function testSubmitFormWithCheckboxesWithoutValue() + public function testSubmitFormWithCheckboxesWithoutValue(): void { $this->module->amOnPage('/form/checkbox_default_value'); $this->module->submitForm('form', ['checkbox1' => true]); $this->assertSame('on', data::get('query')['checkbox1']); } - public function testSubmitFormWithButtons() + public function testSubmitFormWithButtons(): void { $this->module->amOnPage('/form/form_with_buttons'); $this->module->submitForm('form', [ @@ -1375,35 +1375,35 @@ public function testSubmitFormWithButtons() /** * https://github.com/Codeception/Codeception/issues/1409 */ - public function testWrongXpath() + public function testWrongXpath(): void { $this->expectException(MalformedLocatorException::class); $this->module->amOnPage('/'); $this->module->seeElement('//aas[asd}[sd]a[/['); } - public function testWrongCSS() + public function testWrongCSS(): void { $this->expectException(MalformedLocatorException::class); $this->module->amOnPage('/'); $this->module->seeElement('.user#iasosexpectException(MalformedLocatorException::class); $this->module->amOnPage('/'); $this->module->seeElement(['css' => 'hel!1$expectException(MalformedLocatorException::class); $this->module->amOnPage('/'); $this->module->seeElement(['xpath' => 'hellorld']); } - public function testFormWithFilesArray() + public function testFormWithFilesArray(): void { $this->module->amOnPage('/form/example13'); $this->module->attachFile('foo[bar]', 'app/avatar.jpg'); @@ -1415,7 +1415,7 @@ public function testFormWithFilesArray() $this->assertArrayHasKey('baz', $files['foo']['name']); } - public function testFormWithFileSpecialCharNames() + public function testFormWithFileSpecialCharNames(): void { $this->module->amOnPage('/form/example14'); $this->module->attachFile('foo bar', 'app/avatar.jpg'); @@ -1431,7 +1431,7 @@ public function testFormWithFileSpecialCharNames() /** * @Issue https://github.com/Codeception/Codeception/issues/1454 */ - public function testTextFieldByNameFirstNotCss() + public function testTextFieldByNameFirstNotCss(): void { $this->module->amOnPage('/form/example15'); $this->module->fillField('title', 'Special Widget'); @@ -1446,7 +1446,7 @@ public function testTextFieldByNameFirstNotCss() /** * @Issue https://github.com/Codeception/Codeception/issues/1535 */ - public function testCheckingOptionsWithComplexNames() + public function testCheckingOptionsWithComplexNames(): void { $this->module->amOnPage('/form/bug1535'); $this->module->checkOption('#bmessage-topicslinks input[value="4"]'); @@ -1460,7 +1460,7 @@ public function testCheckingOptionsWithComplexNames() * @Issue https://github.com/Codeception/Codeception/issues/1585 * @Issue https://github.com/Codeception/Codeception/issues/1602 */ - public function testUnreachableField() + public function testUnreachableField(): void { $this->module->amOnPage('/form/bug1585'); $this->module->fillField('textarea[name="captions[]"]', 'test2'); @@ -1475,7 +1475,7 @@ public function testUnreachableField() $this->assertContains('davert', $data['users']); } - public function testSubmitAdjacentForms() + public function testSubmitAdjacentForms(): void { $this->module->amOnPage('/form/submit_adjacentforms'); $this->module->submitForm('#form-2', []); @@ -1486,7 +1486,7 @@ public function testSubmitAdjacentForms() $this->assertEquals('Killgore Trout', $data['second-field']); } - public function testSubmitAdjacentFormsByButton() + public function testSubmitAdjacentFormsByButton(): void { $this->module->amOnPage('/form/submit_adjacentforms'); $this->module->fillField('first-field', 'First'); @@ -1509,14 +1509,14 @@ public function testSubmitAdjacentFormsByButton() $this->assertEquals('Second', $data['second-field']); } - public function testArrayField() + public function testArrayField(): void { $this->module->amOnPage('/form/example17'); $this->module->seeInField('input[name="FooBar[bar]"]', 'baz'); $this->module->seeInField('input[name="Food[beer][yum][yeah]"]', 'mmhm'); } - public function testFillFieldSquareBracketNames() + public function testFillFieldSquareBracketNames(): void { $this->module->amOnPage('/form/names-sq-brackets'); $this->module->fillField('//input[@name="input_text"]', 'filling this input'); @@ -1531,7 +1531,7 @@ public function testFillFieldSquareBracketNames() $this->module->fillField('//textarea[@name="textarea[name][]"]', 'filling this textarea most'); } - public function testSelectAndCheckOptionSquareBracketNames() + public function testSelectAndCheckOptionSquareBracketNames(): void { $this->module->amOnPage('/form/names-sq-brackets'); $this->module->selectOption('//input[@name="input_radio_name"]', '1'); @@ -1553,7 +1553,7 @@ public function testSelectAndCheckOptionSquareBracketNames() $this->module->selectOption('//select[@name="select[name][]"]', '1'); } - public function testFillFieldWithAmpersand() + public function testFillFieldWithAmpersand(): void { $this->module->amOnPage('/form/field'); $this->module->fillField('Name', 'this & that'); @@ -1563,35 +1563,35 @@ public function testFillFieldWithAmpersand() $this->assertEquals('this & that', $form['name']); } - public function testSeeInDeactivatedField() + public function testSeeInDeactivatedField(): void { $this->module->amOnPage('/form/complex'); $this->module->seeInField('#disabled_field', 'disabled_field'); $this->module->seeInField('#salutation', 'mr'); } - public function testSwitchToIframe() + public function testSwitchToIframe(): void { $this->module->amOnPage('/iframe'); $this->module->switchToIframe('content'); $this->module->see('Is that interesting?'); $this->module->click('Ссылочка'); } - - public function testGrabMultiple() + + public function testGrabMultiple(): void { $this->module->amOnPage('/info'); - + $arr = $this->module->grabMultiple('#grab-multiple a:first-child'); $this->assertCount(1, $arr); $this->assertEquals('First', $arr[0]); - + $arr = $this->module->grabMultiple('#grab-multiple a'); $this->assertCount(3, $arr); $this->assertEquals('First', $arr[0]); $this->assertEquals('Second', $arr[1]); $this->assertEquals('Third', $arr[2]); - + // href for WebDriver with selenium returns a full link, so testing with ID $arr = $this->module->grabMultiple('#grab-multiple a', 'id'); $this->assertCount(3, $arr); @@ -1603,7 +1603,7 @@ public function testGrabMultiple() /** * @issue https://github.com/Codeception/Codeception/issues/2960 */ - public function testClickMultiByteLink() + public function testClickMultiByteLink(): void { $this->module->amOnPage('/info'); $this->module->click('Franšízy - pobočky'); @@ -1613,7 +1613,7 @@ public function testClickMultiByteLink() /** * @issue https://github.com/Codeception/Codeception/issues/3528 */ - public function testClickThrowsElementNotFoundExceptionWhenTextContainsNumber() + public function testClickThrowsElementNotFoundExceptionWhenTextContainsNumber(): void { $this->expectException(ElementNotFound::class); $this->expectExceptionMessage("'Link 2' is invalid CSS and XPath selector and Link or Button element with 'name=Link 2' was not found."); @@ -1621,14 +1621,14 @@ public function testClickThrowsElementNotFoundExceptionWhenTextContainsNumber() $this->module->click('Link 2'); } - public function testClickExistingLinkWithTextContainingNumber() + public function testClickExistingLinkWithTextContainingNumber(): void { $this->module->amOnPage('/info'); $this->module->click('Link 3'); $this->module->seeCurrentUrlEquals('/cookies'); } - public function testSelectOptionValueSelector() + public function testSelectOptionValueSelector(): void { $this->module->amOnPage('/form/select_selectors'); $this->module->selectOption('age', ['value' => '20']); @@ -1638,7 +1638,7 @@ public function testSelectOptionValueSelector() $this->assertEquals('20', $data['age']); } - public function testSelectOptionTextSelector() + public function testSelectOptionTextSelector(): void { $this->module->amOnPage('/form/select_selectors'); @@ -1649,77 +1649,77 @@ public function testSelectOptionTextSelector() $this->module->seeOptionIsSelected('age', '21'); } - public function testClickButtonInLink() + public function testClickButtonInLink(): void { $this->module->amOnPage('/form/button_in_link'); $this->module->click('More Info'); $this->module->seeCurrentUrlEquals('/info'); } - public function testClickButtonInLinkAndSpan() + public function testClickButtonInLinkAndSpan(): void { $this->module->amOnPage('/form/button_in_link'); $this->module->click('Span Info'); $this->module->seeCurrentUrlEquals('/info'); } - public function testClickButtonInLinkUsingCssLocator() + public function testClickButtonInLinkUsingCssLocator(): void { $this->module->amOnPage('/form/button_in_link'); $this->module->click(['css' => 'input[value="More Info"]']); $this->module->seeCurrentUrlEquals('/info'); } - public function testClickButtonInLinkAndSpanUsingCssLocator() + public function testClickButtonInLinkAndSpanUsingCssLocator(): void { $this->module->amOnPage('/form/button_in_link'); $this->module->click(['css' => 'input[value="Span Info"]']); $this->module->seeCurrentUrlEquals('/info'); } - public function testClickHashLink() + public function testClickHashLink(): void { $this->module->amOnPage('/form/anchor'); $this->module->click('Hash Link'); $this->module->seeCurrentUrlEquals('/form/anchor'); } - public function testClickHashButton() + public function testClickHashButton(): void { $this->module->amOnPage('/form/anchor'); $this->module->click('Hash Button'); $this->module->seeCurrentUrlEquals('/form/anchor'); } - public function testSubmitHashForm() + public function testSubmitHashForm(): void { $this->module->amOnPage('/form/anchor'); $this->module->click('Hash Form'); $this->module->seeCurrentUrlEquals('/form/anchor'); } - public function testClickingRelativeLinkHonoursBaseHref() + public function testClickingRelativeLinkHonoursBaseHref(): void { $this->module->amOnPage('/basehref'); $this->module->click('Relative Link'); $this->module->seeCurrentUrlEquals('/form/example7'); } - public function testSubmittingRelativeFormHonoursBaseHref() + public function testSubmittingRelativeFormHonoursBaseHref(): void { $this->module->amOnPage('/basehref'); $this->module->click('Relative Form'); $this->module->seeCurrentUrlEquals('/form/example5'); } - public function testClickingRelativeLinkInContextHonoursBaseHref() + public function testClickingRelativeLinkInContextHonoursBaseHref(): void { $this->module->amOnPage('/basehref'); $this->module->click('Relative Link', 'p'); $this->module->seeCurrentUrlEquals('/form/example7'); } - public function testSubmittingRelativeForminContextHonoursBaseHref() + public function testSubmittingRelativeForminContextHonoursBaseHref(): void { $this->module->amOnPage('/basehref'); $this->module->fillField('rus', 'test value'); @@ -1727,14 +1727,14 @@ public function testSubmittingRelativeForminContextHonoursBaseHref() $this->module->seeCurrentUrlEquals('/form/example5'); } - public function testClickingFormButtonInContextSubmitsOutOfContextFormElements() + public function testClickingFormButtonInContextSubmitsOutOfContextFormElements(): void { $this->module->amOnPage('/basehref'); $this->module->click('Relative Form', '#button-container'); $this->assertArrayHasKey('rus', data::get('form')); } - public function testAttachFileThrowsCorrectMessageWhenFileDoesNotExist() + public function testAttachFileThrowsCorrectMessageWhenFileDoesNotExist(): void { $filename = 'does-not-exist.jpg'; $expectedMessage = 'File does not exist: ' . codecept_data_dir($filename); @@ -1745,7 +1745,7 @@ public function testAttachFileThrowsCorrectMessageWhenFileDoesNotExist() $this->module->attachFile('Avatar', $filename); } - public function testPasswordArgument() + public function testPasswordArgument(): void { $this->module->amOnPage('/form/password_argument'); $this->module->fillField('password', new PasswordArgument('thisissecret')); From f7c5f6adf394f47b1a257e8289b7a4b3ce456496 Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Mon, 17 Mar 2025 14:44:27 +0100 Subject: [PATCH 26/26] Update PhpBrowser.php: Adding note about IDN and punycode --- src/Codeception/Module/PhpBrowser.php | 50 ++++++++++++--------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/src/Codeception/Module/PhpBrowser.php b/src/Codeception/Module/PhpBrowser.php index 5049f5c..b8ce650 100644 --- a/src/Codeception/Module/PhpBrowser.php +++ b/src/Codeception/Module/PhpBrowser.php @@ -22,13 +22,6 @@ * * If test fails stores last shown page in 'output' dir. * - * ## Status - * - * * Maintainer: **davert** - * * Stability: **stable** - * * Contact: codeception@codeception.com - * - * * ## Configuration * * * url *required* - start url of your app @@ -42,28 +35,29 @@ * * .. those and other [Guzzle Request options](https://docs.guzzlephp.org/en/latest/request-options.html) * * - * ### Example (`acceptance.suite.yml`) - * - * modules: - * enabled: - * - PhpBrowser: - * url: 'http://localhost' - * auth: ['admin', '123345'] - * curl: - * CURLOPT_RETURNTRANSFER: true - * cookies: - * cookie-1: - * Name: userName - * Value: john.doe - * cookie-2: - * Name: authToken - * Value: 1abcd2345 - * Domain: subdomain.domain.com - * Path: /admin/ - * Expires: 1292177455 - * Secure: true - * HttpOnly: false + * ### Example (`Acceptance.suite.yml`) * + * ```yaml + * modules: + * enabled: + * - PhpBrowser: + * url: 'http://localhost' # Internationalized domain names (IDN) need to be passed in punycode + * auth: ['admin', '123345'] + * curl: + * CURLOPT_RETURNTRANSFER: true + * cookies: + * cookie-1: + * Name: userName + * Value: john.doe + * cookie-2: + * Name: authToken + * Value: 1abcd2345 + * Domain: subdomain.domain.com + * Path: /admin/ + * Expires: 1292177455 + * Secure: true + * HttpOnly: false + * ``` * * All SSL certification checks are disabled by default. * Use Guzzle request options to configure certifications and others.