diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 2531c68..8c7446d 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,16 +1,31 @@ { + "name": "codeception-github-reporter", "dockerComposeFile": [ "../docker-compose.yml" ], "service": "php", "shutdownAction": "none", "workspaceFolder": "/var/www/", - "extensions": [ - "bmewburn.vscode-intelephense-client", - "hbenl.vscode-test-explorer", - "recca0120.vscode-phpunit", - "eamodio.gitlens", - "mhutchie.git-graph", - "junstyle.php-cs-fixer" - ] + "customizations": { + "vscode": { + "extensions": [ + "bmewburn.vscode-intelephense-client", + "hbenl.vscode-test-explorer", + "recca0120.vscode-phpunit", + "eamodio.gitlens", + "mhutchie.git-graph", + "junstyle.php-cs-fixer", + "janbn.git-last-commit-message", + "kasik96.latte", + "seatonjiang.gitmoji-vscode" + ] + } + }, + "features": { + "ghcr.io/devcontainers/features/common-utils:2.5.7": { + "installZsh": true, + "configureZshAsDefaultShell": true, + "upgradePackages": true + } + } } \ No newline at end of file diff --git a/.env.example b/.env.example index 03ba0d2..eaa0c5c 100644 --- a/.env.example +++ b/.env.example @@ -1,9 +1,9 @@ -PHP_VERSION=56|73|74|80 -GITHUB_OWNER: Owner of repository -GITHUB_REPO: Name of repository -GITHUB_PR_NUMBER: Number of pull request of repository -GITHUB_TOKEN: Token of the user's github who will post the comment -TEST_LANG: Language -TEST_TITLE: Message to show in title -TEST_FOOTER: Show footer with version of PHP -IMGBB_TOKEN: Token to upload image acceptance test \ No newline at end of file +PHP_VERSION=74|80|81|82|83 +GITHUB_OWNER=Owner of repository +GITHUB_REPO=Name of repository +GITHUB_PR_NUMBER=Number of pull request of repository +GITHUB_TOKEN=Token of the user's github who will post the comment +TEST_LANG=Language +TEST_TITLE=Message to show in title +TEST_FOOTER=Show footer with version of PHP +IMGBB_TOKEN=Token to upload image acceptance test \ No newline at end of file diff --git a/.github/workflows/ci-56.yml b/.github/workflows/ci-56.yml deleted file mode 100644 index bd69417..0000000 --- a/.github/workflows/ci-56.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: PHP 5.6 - -on: - push: - branches: - - master - - pull_request: - -jobs: - - test: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - name: Prepare code - run: | - touch .env - echo "GITHUB_OWNER=likesistemas" >> .env - echo "GITHUB_REPO=codeception-github-reporter" >> .env - echo "GITHUB_PR_NUMBER=${{github.event.number}}" >> .env - echo "GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> .env - echo "IMGBB_TOKEN=${{ secrets.IMGBB_TOKEN }}" >> .env - echo "PHP_VERSION=56" >> .env - - - name: Run tests - run: | - docker-compose up -d - echo $(docker run -t --network github jwilder/dockerize -wait http://nginx/ -timeout 60s) - docker-compose ps - docker-compose logs php - docker-compose exec -T php composer test:ci - docker-compose down - \ No newline at end of file diff --git a/.github/workflows/ci-73.yml b/.github/workflows/ci-73.yml deleted file mode 100644 index e21676a..0000000 --- a/.github/workflows/ci-73.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: PHP 7.3 - -on: - - push: - branches: - - master - - pull_request: - -jobs: - - test: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - name: Prepare code - run: | - touch .env - echo "GITHUB_OWNER=likesistemas" >> .env - echo "GITHUB_REPO=codeception-github-reporter" >> .env - echo "GITHUB_PR_NUMBER=${{github.event.number}}" >> .env - echo "GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> .env - echo "IMGBB_TOKEN=${{ secrets.IMGBB_TOKEN }}" >> .env - echo "PHP_VERSION=73" >> .env - - - name: Run tests - run: | - docker-compose up -d - echo $(docker run -t --network github jwilder/dockerize -wait http://nginx/ -timeout 60s) - docker-compose ps - docker-compose logs php - docker-compose exec -T php composer test:ci - docker-compose down \ No newline at end of file diff --git a/.github/workflows/ci-74.yml b/.github/workflows/ci-74.yml deleted file mode 100644 index e3638d8..0000000 --- a/.github/workflows/ci-74.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: PHP 7.4 - -on: - - push: - branches: - - master - - pull_request: - -jobs: - - test: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - name: Prepare code - run: | - touch .env - echo "GITHUB_OWNER=likesistemas" >> .env - echo "GITHUB_REPO=codeception-github-reporter" >> .env - echo "GITHUB_PR_NUMBER=${{github.event.number}}" >> .env - echo "GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> .env - echo "IMGBB_TOKEN=${{ secrets.IMGBB_TOKEN }}" >> .env - echo "PHP_VERSION=74" >> .env - - - name: Run tests - run: | - docker-compose up -d - echo $(docker run -t --network github jwilder/dockerize -wait http://nginx/ -timeout 60s) - docker-compose ps - docker-compose logs php - docker-compose exec -T php composer test:ci - docker-compose down \ No newline at end of file diff --git a/.github/workflows/ci-80.yml b/.github/workflows/ci-80.yml deleted file mode 100644 index 6b2c4cd..0000000 --- a/.github/workflows/ci-80.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: PHP 8.0 - -on: - - push: - branches: - - master - - pull_request: - -jobs: - - test: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - name: Prepare code - run: | - touch .env - echo "GITHUB_OWNER=likesistemas" >> .env - echo "GITHUB_REPO=codeception-github-reporter" >> .env - echo "GITHUB_PR_NUMBER=${{github.event.number}}" >> .env - echo "GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> .env - echo "IMGBB_TOKEN=${{ secrets.IMGBB_TOKEN }}" >> .env - echo "PHP_VERSION=80" >> .env - - - name: Run tests - run: | - docker-compose up -d - echo $(docker run -t --network github jwilder/dockerize -wait http://nginx/ -timeout 60s) - docker-compose ps - docker-compose logs php - docker-compose exec -T php composer test:ci - docker-compose down \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..aff494f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,67 @@ +name: CI + +on: + push: + branches: + - master + + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + + test: + strategy: + matrix: + PHP: [74, 80, 81, 82, 83] + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + + - name: Prepare code + env: + PHP_VERSION: ${{ matrix.PHP }} + run: | + touch .env + echo "GITHUB_TOKEN=${{ secrets.GH_TOKEN }}" >> .env + echo "PHP_VERSION=$PHP_VERSION" >> .env + + - name: Up environment + run: | + docker compose up -d + + - name: Wait environment + run: | + echo $(docker compose -f docker-compose.wait.yml run --rm wait) + + - name: Environment logs + run: | + docker compose ps + docker compose logs php + + - name: Run Lint + run: | + docker compose exec -T php composer lint + + - name: Run PHP Unit + continue-on-error: true + run: | + docker compose exec -T php composer test + + - name: Run PHP Stan + run: | + docker compose exec -T php composer analyse + + - name: Run PHP CS Fixer + run: | + docker compose exec -T php composer fix:ci + + - name: Desligando ambiente + if: ${{ always() }} + run: | + docker compose exec -T php rm -Rf vendor/ .env + docker compose down --remove-orphans \ No newline at end of file diff --git a/.gitignore b/.gitignore index dbd603c..22bf14f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .history/ .env composer.lock +.php-cs-fixer.cache \ No newline at end of file diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 0000000..d7026ae --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,53 @@ + true, + 'array_syntax' => ['syntax' => 'short'], + 'multiline_whitespace_before_semicolons' => false, + 'echo_tag_syntax' => false, + 'no_unused_imports' => true, + 'not_operator_with_successor_space' => true, + 'no_useless_else' => true, + 'ordered_imports' => ['sort_algorithm' => 'none', 'imports_order' => ['const', 'class', 'function']], + 'phpdoc_add_missing_param_annotation' => true, + 'phpdoc_indent' => true, + 'phpdoc_no_package' => true, + 'phpdoc_order' => true, + 'phpdoc_separation' => true, + 'phpdoc_single_line_var_spacing' => true, + 'phpdoc_trim' => true, + 'phpdoc_var_without_name' => true, + 'phpdoc_to_comment' => true, + 'single_quote' => true, + 'ternary_operator_spaces' => true, + 'trailing_comma_in_multiline' => true, + 'trim_array_spaces' => true, + 'curly_braces_position' => [ + 'classes_opening_brace' => 'same_line', + 'functions_opening_brace' => 'same_line', + ], + 'visibility_required' => ['elements' => ['property', 'method']], +]; + +$excludes = [ + 'vendor', + '.vscode', + '.github', + '.devcontainer', + 'tests/_support/_generated/', +]; + +$finder = PhpCsFixer\Finder::create() + ->in(__DIR__) + ->exclude($excludes) + ->notName('README.md') + ->notName('*.xml') + ->notName('*.yml') + ->notName('_ide_helper.php') +; + +return (new PhpCsFixer\Config()) + ->setRules($rules) + ->setFinder($finder) + ->setIndent("\t") +; diff --git a/.php_cs b/.php_cs deleted file mode 100644 index 1698abd..0000000 --- a/.php_cs +++ /dev/null @@ -1,43 +0,0 @@ - true, - 'array_syntax' => ['syntax' => 'short'], - 'no_multiline_whitespace_before_semicolons' => true, - 'no_short_echo_tag' => true, - 'no_unused_imports' => true, - 'not_operator_with_successor_space' => true, - 'no_useless_else' => true, - 'ordered_imports' => ['sort_algorithm' => 'none', 'imports_order' => ['const', 'class', 'function']], - 'phpdoc_add_missing_param_annotation' => true, - 'phpdoc_indent' => true, - 'phpdoc_no_package' => true, - 'phpdoc_order' => true, - 'phpdoc_separation' => true, - 'phpdoc_single_line_var_spacing' => true, - 'phpdoc_trim' => true, - 'phpdoc_var_without_name' => true, - 'phpdoc_to_comment' => true, - 'single_quote' => true, - 'ternary_operator_spaces' => true, - 'trailing_comma_in_multiline_array' => true, - 'trim_array_spaces' => true -]; - -$excludes = [ - 'vendor' -]; - -$finder = PhpCsFixer\Finder::create() - ->in(__DIR__) - ->exclude($excludes) - ->notName('README.md') - ->notName('*.xml') - ->notName('*.yml') - ->notName('_ide_helper.php') -; - -return PhpCsFixer\Config::create() - ->setRules($rules) - ->setFinder($finder) -; \ No newline at end of file diff --git a/composer.json b/composer.json index a505f56..e68670b 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ } ], "require": { - "php": ">=5.6", + "php": ">=7.4", "ext-curl": "*", "guzzlehttp/guzzle": "^6.0 | ^7.0" }, @@ -25,15 +25,25 @@ } }, "require-dev": { - "phpunit/phpunit": "^5.7 || ^9.0", - "codeception/codeception": "^4.1", - "codeception/module-asserts": "^1.0.0", - "codeception/module-webdriver": "^1.2", - "codeception/module-rest": "^1.2", - "codeception/module-phpbrowser": "^1.0", - "codeception/module-db": "^1.1" + "phpunit/phpunit": "^9.0 || ^10.0", + "codeception/codeception": "^4.1 || ^5.0", + "codeception/module-asserts": "^1.0 || ^2.0", + "codeception/module-webdriver": "^1.2 || ^4.0", + "codeception/module-rest": "^1.2 || ^3.0", + "codeception/module-phpbrowser": "^1.0 || ^2.0", + "codeception/module-db": "^1.1 || ^3.0", + "phpstan/phpstan": "^2.1", + "friendsofphp/php-cs-fixer": "^3.95", + "php-parallel-lint/php-parallel-lint": "^1.4" }, "scripts": { - "test:ci": "codecept run --no-exit --ext \"Like\\Codeception\\GitHubReporter\"" + "fix": "php-cs-fixer fix", + "fix:ci": "php-cs-fixer fix --dry-run --stop-on-violation", + "test": "codecept run --no-exit", + "test:ci": "codecept run --no-exit --ext \"Like\\Codeception\\GitHubReporter\"", + "lint": "parallel-lint --colors --exclude vendor/ --exclude ./tests/_support/_generated/ .", + "analyse": ["codecept build","phpstan analyse"], + "analyse:baseline": "phpstan analyse --generate-baseline", + "refactor": "rector process" } } diff --git a/docker-compose.wait.yml b/docker-compose.wait.yml new file mode 100644 index 0000000..788d847 --- /dev/null +++ b/docker-compose.wait.yml @@ -0,0 +1,12 @@ +networks: + github: + name: github + driver: bridge + +services: + + wait: + image: jwilder/dockerize:latest + command: -wait tcp://php:9000 -timeout 120s + networks: + - github diff --git a/docker-compose.yml b/docker-compose.yml index 6940ee6..b49951b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,3 @@ -version: '3.7' networks: github: name: github @@ -18,13 +17,11 @@ services: - 8081:80 networks: - github - links: - - php depends_on: - php php: - image: likesistemas/php-dev:${PHP_VERSION:-56} + image: likesistemas/php-dev:${PHP_VERSION:-74} environment: - GITHUB_TOKEN=$GITHUB_TOKEN - GITHUB_OWNER=$GITHUB_OWNER @@ -45,9 +42,6 @@ services: - 4444 networks: - github - links: - - php - - nginx depends_on: - php - nginx \ No newline at end of file diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..4258e5d --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,25 @@ +parameters: + ignoreErrors: + - + message: '#^Argument of an invalid type string supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable + count: 1 + path: src/GitHubReporter.php + + - + message: '#^Dead catch \- InvalidArgumentException is already caught above\.$#' + identifier: catch.alreadyCaught + count: 1 + path: src/GitHubReporter.php + + - + message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertTrue\(\) with false will always evaluate to false\.$#' + identifier: method.impossibleType + count: 1 + path: tests/unit/GitHubReporterTest.php + + - + message: '#^Method PHPUnit\\Framework\\Assert\:\:assertTrue\(\) invoked with 0 parameters, 1\-2 required\.$#' + identifier: arguments.count + count: 1 + path: tests/unit/GitHubReporterTest.php diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..49712ca --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,15 @@ +includes: + - phpstan-baseline.neon + +parameters: + level: 5 + paths: + - src + - tests + scanDirectories: + - tests/_support/_generated/ + bootstrapFiles: + - vendor/codeception/codeception/autoload.php + excludePaths: + analyse: + - tests/_support/_generated/ \ No newline at end of file diff --git a/public/index.php b/public/index.php index b4a8fbb..fe448ae 100644 --- a/public/index.php +++ b/public/index.php @@ -1,3 +1,3 @@ getNumberOfParameters() > 1 && $eventNumber !== null) { + $args[] = $eventNumber; + } + + $method->invokeArgs($this, $args); + } } diff --git a/src/GitHubReporter.php b/src/GitHubReporter.php index d603719..3db5ea3 100644 --- a/src/GitHubReporter.php +++ b/src/GitHubReporter.php @@ -7,6 +7,8 @@ use Codeception\Events; use Codeception\Extension; use Codeception\Test\Descriptor; +use Codeception\Test\Interfaces\Descriptive; +use Codeception\Test\Interfaces\Plain; use Codeception\Test\Interfaces\ScenarioDriven; use Codeception\TestInterface; use GuzzleHttp\Client; @@ -14,237 +16,245 @@ use InvalidArgumentException; use LogicException; -class GitHubReporter extends Extension -{ - - /** @var array */ - private $lang; - - /** @var string */ - private $currentTest = ''; - - /** @var string */ - private $currentTestSuit; - - /** @var array */ - private $tests = []; - - /** @var array */ - private $errors = []; - - /** @var Console */ - protected $standardReporter; - - public function _initialize() - { - $this->options['silent'] = false; // turn on printing for this extension - $this->_reconfigure(['settings' => ['silent' => true]]); // turn off printing for everything else - $this->standardReporter = new Console($this->options); - $this->lang = Lang::getLang(getenv('TEST_LANG')); - } - - // we are listening for events - public static $events = [ - Events::SUITE_BEFORE => 'beforeSuite', - Events::SUITE_AFTER => 'afterSuite', - Events::TEST_END => 'after', - Events::TEST_SUCCESS => 'success', - Events::TEST_FAIL => 'fail', - Events::TEST_ERROR => 'error', - Events::TEST_FAIL_PRINT => 'printFailed', - Events::RESULT_PRINT_AFTER => 'result', - ]; - - protected function _write($message) - { - $this->currentTest .= $message; - } - - protected function _writeln($message) - { - $this->currentTest .= $message; - - if (strlen($this->currentTest) > 0) { - $this->tests[$this->currentTestSuit][] = $this->currentTest; - $this->currentTest = ''; - } - } - - public function beforeSuite($e) - { - $this->currentTestSuit = ucfirst($e->getSuite()->getName()) . " Tests ({$e->getSuite()->count()})"; - $this->standardReporter->beforeSuite($e); - } - - public function afterSuite($e) - { - $this->standardReporter->afterSuite($e); - } - - public function success($e) - { - $this->_write(':heavy_check_mark: '); - $this->standardReporter->testSuccess($e); - } - - public function fail($e) - { - $this->_write(':x: '); - $this->standardReporter->testFail($e); - } - - public function error($e) - { - $this->_write(':o: '); - $this->standardReporter->testError($e); - } - - public function skipped() - { - $this->_write('- [ ] :white_circle: '); - $this->standardReporter->testSkipped($e); - } - - public function after(TestEvent $e) - { - $seconds_input = $e->getTime(); - $seconds = (int) ($milliseconds = (int) ($seconds_input * 1000)) / 1000; - $time = ($seconds % 60).(($milliseconds === 0) ? '' : '.'.$milliseconds); - - $this->_write(Descriptor::getTestSignature($e->getTest())); - $this->_writeln(' ('.$time.'s)'); - - $this->standardReporter->endTest($e); - } - - public function printFailed(FailEvent $e) - { - $failedTest = $e->getTest(); - $fail = $e->getFail(); - - $error = []; - $error[] = $e->getCount().') '.Descriptor::getTestAsString($failedTest); - $error[] = Descriptor::getTestFullName($failedTest); - if ($fail->getMessage()) { - $error[] = $fail->getMessage(); - } - - if ($failedTest instanceof ScenarioDriven) { - $reports = $this->getReports($failedTest); - if ($reports) { - $error[] = $reports; - } - } else { - $trace = $this->getExceptionTrace($fail); - if ($trace) { - $error += $trace; - } - } - - $this->errors[] = $error; - - $this->standardReporter->printFail($e); - } - - use StackTrace; - - private function getReports(TestInterface $failedTest) - { - $reports = $failedTest->getMetadata()->getReports(); - if (isset($reports['png'])) { - $token = getenv('IMGBB_TOKEN'); - - try { - if (! $token) { - throw new InvalidArgumentException('To upload it informs the environment variable `TOKEN_IMGBB`.'); - } - - $upload = new UploadImage($token); - $url = $upload->upload($reports['png']); - return sprintf($this->lang['image'], $url); - } catch (RequestException $ex) { - $this->writeln("Error on upload image: {$ex->getMessage()}"); - } catch (LogicException $ex) { - $this->writeln($ex->getMessage()); - } catch (InvalidArgumentException $ex) { - $this->writeln($ex->getMessage()); - } - } - } - - public function result() - { - $TITLE = getenv('TEST_TITLE'); - $FOOTER = (getenv('TEST_FOOTER') ?: 'true') === 'true'; - $OWNER = getenv('GITHUB_OWNER'); - $REPO = getenv('GITHUB_REPO'); - $PR_NUMBER = getenv('GITHUB_PR_NUMBER'); - $TOKEN = getenv('GITHUB_TOKEN'); - - $body = $this->getBodyMessage($this->lang, $TITLE, $FOOTER); - $this->writeln(''); - $this->writeln($body); - - try { - if (! $OWNER) { - throw new InvalidArgumentException('It is necessary to send the environment variable `GITHUB_OWNER`.'); - } - - if (! $REPO) { - throw new InvalidArgumentException('It is necessary to send the environment variable `GITHUB_REPO`.'); - } - - if (! $PR_NUMBER) { - throw new InvalidArgumentException('It is necessary to send the environment variable `GITHUB_PR_NUMBER`.'); - } - - if (! $TOKEN) { - throw new InvalidArgumentException('It is necessary to send the environment variable `GITHUB_TOKEN`.'); - } - - $URL = "https://api.github.com/repos/{$OWNER}/{$REPO}/issues/${PR_NUMBER}/comments"; - - $client = new Client(); - $client->request('POST', $URL, [ - 'body' => json_encode(['body' => $body]), - 'auth' => ['token', $TOKEN], - ]); - } catch (RequestException $ex) { - $this->writeln("Error on comment in github: {$ex->getMessage()}"); - } catch (InvalidArgumentException $ex) { - $this->writeln("Error on comment in github: {$ex->getMessage()}"); - } - } - - private function getBodyMessage(array $lang, $title = null, $footer = true) - { - $message = ''; - - if ($title) { - $message .= "**$title**\n"; - } - - if (count($this->errors) == 0) { - $message .= "{$lang['success']}\n"; - } else { - $message .= sprintf($lang['fail'], count($this->errors))."\n\n"; - foreach ($this->errors as $error) { - $message .= "```Markdown\n".join("\n", $error)."\n```\n"; - } - $message .= "\n\n"; - } - - foreach ($this->tests as $suiteName => $suiteTests) { - $message .= ''; - $message .= "{$suiteName}\n"; - $message .= '' . join('', $suiteTests) . ''; - $message .= ''; - } - - if ($footer) { - $message .= "\n\n*" . sprintf($lang['footer'], 'PHP v' . phpversion()) . '*'; - } - - return $message; - } +class GitHubReporter extends Extension { + use StackTrace; + + /** @var array */ + private $lang; + + /** @var string */ + private $currentTest = ''; + + /** @var string */ + private $currentTestSuit; + + /** @var array */ + private $tests = []; + + /** @var array */ + private $errors = []; + + /** @var Console */ + protected $standardReporter; + + public function _initialize(): void { + $this->options['silent'] = false; // turn on printing for this extension + $this->_reconfigure(['settings' => ['silent' => true]]); // turn off printing for everything else + $this->standardReporter = new Console($this->options); + $this->lang = Lang::getLang(getenv('TEST_LANG')); + } + + // we are listening for events + public static $events = [ + Events::SUITE_BEFORE => 'beforeSuite', + Events::SUITE_AFTER => 'afterSuite', + Events::TEST_END => 'after', + Events::TEST_SUCCESS => 'success', + Events::TEST_FAIL => 'fail', + Events::TEST_ERROR => 'error', + Events::TEST_FAIL_PRINT => 'printFailed', + Events::RESULT_PRINT_AFTER => 'result', + ]; + + protected function _write($message) { + $this->currentTest .= $message; + } + + protected function _writeln($message) { + $this->currentTest .= $message; + + if (strlen($this->currentTest) > 0) { + $this->tests[$this->currentTestSuit][] = $this->currentTest; + $this->currentTest = ''; + } + } + + public function beforeSuite($e) { + $this->currentTestSuit = ucfirst($e->getSuite()->getName()) . " Tests ({$e->getSuite()->count()})"; + $this->standardReporter->beforeSuite($e); + } + + public function afterSuite($e) { + $this->standardReporter->afterSuite($e); + } + + public function success($e) { + $this->_write(':heavy_check_mark: '); + $this->standardReporter->testSuccess($e); + } + + public function fail($e) { + $this->_write(':x: '); + $this->standardReporter->testFail($e); + } + + public function error($e) { + $this->_write(':o: '); + $this->standardReporter->testError($e); + } + + public function skipped($e) { + $this->_write('- [ ] :white_circle: '); + $this->standardReporter->testSkipped($e); + } + + public function after(TestEvent $e) { + $seconds_input = $e->getTime(); + $seconds = (int) ($milliseconds = (int) ($seconds_input * 1000)) / 1000; + $time = ($seconds % 60).(($milliseconds === 0) ? '' : '.'.$milliseconds); + + $this->_write($this->getTestSignature($e->getTest())); + $this->_writeln(' ('.$time.'s)'); + + $this->standardReporter->endTest($e); + } + + public function printFailed(FailEvent $e, int $eventNumber): void { + $failedTest = $e->getTest(); + $fail = $e->getFail(); + + $error = []; + $error[] = $eventNumber . ') ' . $this->getTestAsString($failedTest); + $error[] = $this->getTestFullName($failedTest); + if ($fail->getMessage()) { + $error[] = $fail->getMessage(); + } + + if ($failedTest instanceof ScenarioDriven) { + $reports = $this->getReports($failedTest); + if ($reports) { + $error[] = $reports; + } + } else { + $trace = $this->getExceptionTrace($fail); + if ($trace) { + $error += $trace; + } + } + + $this->errors[] = $error; + + $this->standardReporter->printFail($e, $eventNumber); + } + + private function getReports(TestInterface $failedTest) { + $reports = $failedTest->getMetadata()->getReports(); + if (isset($reports['png'])) { + $token = getenv('IMGBB_TOKEN'); + + try { + if (! $token) { + throw new InvalidArgumentException('To upload it informs the environment variable `TOKEN_IMGBB`.'); + } + + $upload = new UploadImage($token); + $url = $upload->upload($reports['png']); + return sprintf($this->lang['image'], $url); + } catch (RequestException $ex) { + $this->writeln("Error on upload image: {$ex->getMessage()}"); + } catch (LogicException $ex) { + $this->writeln($ex->getMessage()); + } catch (InvalidArgumentException $ex) { + $this->writeln($ex->getMessage()); + } + } + } + + private function getTestSignature(TestInterface $test): string { + if ($test instanceof Descriptive) { + return Descriptor::getTestSignature($test); + } + + return method_exists($test, 'toString') ? $test->toString() : get_class($test); + } + + private function getTestAsString(TestInterface $test): string { + if ($test instanceof Descriptive) { + return Descriptor::getTestAsString($test); + } + + return method_exists($test, 'toString') ? $test->toString() : get_class($test); + } + + private function getTestFullName(TestInterface $test): string { + if ($test instanceof Descriptive || $test instanceof Plain) { + return Descriptor::getTestFullName($test); + } + + return method_exists($test, 'toString') ? $test->toString() : get_class($test); + } + + public function result() { + $TITLE = getenv('TEST_TITLE'); + $FOOTER = (getenv('TEST_FOOTER') ?: 'true') === 'true'; + $OWNER = getenv('GITHUB_OWNER'); + $REPO = getenv('GITHUB_REPO'); + $PR_NUMBER = getenv('GITHUB_PR_NUMBER'); + $TOKEN = getenv('GITHUB_TOKEN'); + + $body = $this->getBodyMessage($this->lang, $TITLE, $FOOTER); + $this->writeln(''); + $this->writeln($body); + + try { + if (! $OWNER) { + throw new InvalidArgumentException('It is necessary to send the environment variable `GITHUB_OWNER`.'); + } + + if (! $REPO) { + throw new InvalidArgumentException('It is necessary to send the environment variable `GITHUB_REPO`.'); + } + + if (! $PR_NUMBER) { + throw new InvalidArgumentException('It is necessary to send the environment variable `GITHUB_PR_NUMBER`.'); + } + + if (! $TOKEN) { + throw new InvalidArgumentException('It is necessary to send the environment variable `GITHUB_TOKEN`.'); + } + + $URL = "https://api.github.com/repos/{$OWNER}/{$REPO}/issues/${PR_NUMBER}/comments"; + + $client = new Client(); + $client->request('POST', $URL, [ + 'body' => json_encode(['body' => $body]), + 'auth' => ['token', $TOKEN], + ]); + } catch (RequestException $ex) { + $this->writeln("Error on comment in github: {$ex->getMessage()}"); + } catch (InvalidArgumentException $ex) { + $this->writeln("Error on comment in github: {$ex->getMessage()}"); + } + } + + private function getBodyMessage(array $lang, $title = null, $footer = true) { + $message = ''; + + if ($title) { + $message .= "**$title**\n"; + } + + if (count($this->errors) == 0) { + $message .= "{$lang['success']}\n"; + } else { + $message .= sprintf($lang['fail'], count($this->errors))."\n\n"; + foreach ($this->errors as $error) { + $message .= "```Markdown\n".join("\n", $error)."\n```\n"; + } + $message .= "\n\n"; + } + + foreach ($this->tests as $suiteName => $suiteTests) { + $message .= ''; + $message .= "{$suiteName}\n"; + $message .= '' . join('', $suiteTests) . ''; + $message .= ''; + } + + if ($footer) { + $message .= "\n\n*" . sprintf($lang['footer'], 'PHP v' . phpversion()) . '*'; + } + + return $message; + } } diff --git a/src/Lang.php b/src/Lang.php index 6e887f6..5d930fd 100644 --- a/src/Lang.php +++ b/src/Lang.php @@ -2,36 +2,33 @@ namespace Like\Codeception; -class Lang -{ - const LANG_DEFAULT = 'pt-br'; +class Lang { + public const LANG_DEFAULT = 'pt-br'; - private static $langs = [ - 'pt-br' => [ - 'success' => ':sunglasses: Parabéns, seus testes passaram...', - 'fail' => ':rage: Que pena, ocorreram %u erro(s) em seus testes!', - 'footer' => 'Testes foram realizados usando %s', - 'image' => 'Visualizar imagem em %s', - ], - 'en-us' => [ - 'success' => ':sunglasses: Congratulations, your tests have passed...', - 'fail' => ':rage: Your tests failed, there were %u errors!', - 'footer' => 'Tests were performed using %s', - 'image' => 'To view image in %s', - ], - ]; + private static $langs = [ + 'pt-br' => [ + 'success' => ':sunglasses: Parabéns, seus testes passaram...', + 'fail' => ':rage: Que pena, ocorreram %u erro(s) em seus testes!', + 'footer' => 'Testes foram realizados usando %s', + 'image' => 'Visualizar imagem em %s', + ], + 'en-us' => [ + 'success' => ':sunglasses: Congratulations, your tests have passed...', + 'fail' => ':rage: Your tests failed, there were %u errors!', + 'footer' => 'Tests were performed using %s', + 'image' => 'To view image in %s', + ], + ]; - public static function getLang($lang) - { - if (! isset(self::$langs[$lang])) { - $lang = self::LANG_DEFAULT; - } + public static function getLang($lang) { + if (! isset(self::$langs[$lang])) { + $lang = self::LANG_DEFAULT; + } - return self::$langs[$lang]; - } + return self::$langs[$lang]; + } - public static function add($lang, $data) - { - self::$langs[$lang] = $data; - } + public static function add($lang, $data) { + self::$langs[$lang] = $data; + } } diff --git a/src/StackTrace.php b/src/StackTrace.php index e8fcc6f..dfda6cb 100644 --- a/src/StackTrace.php +++ b/src/StackTrace.php @@ -4,50 +4,56 @@ use Codeception\Lib\Console\Message; -trait StackTrace -{ - public function getExceptionTrace($e) - { - $lines = []; - - if ($e instanceof \PHPUnit\Framework\SkippedTestCase or $e instanceof \PHPUnit\Framework\IncompleteTestCase) { - return; - } - - $trace = \PHPUnit\Util\Filter::getFilteredStacktrace($e, false); - - $i = 0; - foreach ($trace as $step) { - $i++; - - $message = $this->message($i)->prepend('#')->width(4); - - if (! isset($step['file'])) { - foreach (['class', 'type', 'function'] as $info) { - if (! isset($step[$info])) { - continue; - } - $message->append($step[$info]); - } - $lines[] = $message->getMessage(); - continue; - } - $message->append($step['file'] . ':' . $step['line']); - $lines[] = $message->getMessage(); - } - - if (method_exists($e, 'getPrevious')) { - $prev = $e->getPrevious(); - if ($prev) { - $lines += $this->printExceptionTrace($prev); - } - } - - return $lines; - } - - private function message($message) - { - return new Message($message); - } +trait StackTrace { + public function getExceptionTrace($e) { + $lines = []; + + if ($this->isSkippedOrIncomplete($e)) { + return; + } + + $trace = \PHPUnit\Util\Filter::getFilteredStacktrace($e); + + $i = 0; + foreach ($trace as $step) { + $i++; + + $message = $this->message($i)->prepend('#')->width(4); + + if (! isset($step['file'])) { + foreach (['class', 'type', 'function'] as $info) { + if (! isset($step[$info])) { + continue; + } + $message->append($step[$info]); + } + $lines[] = $message->getMessage(); + continue; + } + $message->append($step['file'] . ':' . $step['line']); + $lines[] = $message->getMessage(); + } + + if (method_exists($e, 'getPrevious')) { + $prev = $e->getPrevious(); + if ($prev) { + $lines += $this->getExceptionTrace($prev); + } + } + + return $lines; + } + + private function message($message) { + return new Message($message); + } + + private function isSkippedOrIncomplete($e): bool { + $phpUnit10Skipped = class_exists('PHPUnit\\Event\\Test\\Skipped') && $e instanceof \PHPUnit\Event\Test\Skipped; + $phpUnit10Incomplete = class_exists('PHPUnit\\Event\\Test\\MarkedIncomplete') && $e instanceof \PHPUnit\Event\Test\MarkedIncomplete; + $legacySkipped = class_exists('PHPUnit\\Framework\\SkippedTest') && $e instanceof \PHPUnit\Framework\SkippedTest; + $legacyIncomplete = class_exists('PHPUnit\\Framework\\IncompleteTest') && $e instanceof \PHPUnit\Framework\IncompleteTest; + + return $phpUnit10Skipped || $phpUnit10Incomplete || $legacySkipped || $legacyIncomplete; + } } diff --git a/src/UploadImage.php b/src/UploadImage.php index 21d6cf3..6826e08 100644 --- a/src/UploadImage.php +++ b/src/UploadImage.php @@ -5,49 +5,46 @@ use GuzzleHttp\Client; use LogicException; -class UploadImage -{ - const URL = 'https://api.imgbb.com/1/upload'; - const EXPIRATION_IN_SECONDS = 10080; // One week - - /** @var string */ - private $token; - - public function __construct($token) - { - $this->token = $token; - } - - public function upload($fileToUpload) - { - $url = self::URL . - '?expiration=' . self::EXPIRATION_IN_SECONDS . - '&key=' . $this->token; - - $client = new Client(); - $response = $client->request('POST', $url, [ - 'multipart' => [ - [ - 'name' => 'image', - 'contents' => fopen($fileToUpload, 'r'), - ], - ], - ]); - - $body = (string) $response->getBody(); - if (! $body) { - throw new LogicException('Body is empty.'); - } - - $json = json_decode($body, true); - if (! is_array($json)) { - throw new LogicException('Body is json. Body: ' . $body); - } - - if (! isset($json['data']) || ! isset($json['data']['url'])) { - throw new LogicException('Body is valid json. Body: ' . $body); - } - - return $json['data']['url']; - } +class UploadImage { + public const URL = 'https://api.imgbb.com/1/upload'; + public const EXPIRATION_IN_SECONDS = 10080; // One week + + /** @var string */ + private $token; + + public function __construct($token) { + $this->token = $token; + } + + public function upload($fileToUpload) { + $url = self::URL . + '?expiration=' . self::EXPIRATION_IN_SECONDS . + '&key=' . $this->token; + + $client = new Client(); + $response = $client->request('POST', $url, [ + 'multipart' => [ + [ + 'name' => 'image', + 'contents' => fopen($fileToUpload, 'r'), + ], + ], + ]); + + $body = (string) $response->getBody(); + if (! $body) { + throw new LogicException('Body is empty.'); + } + + $json = json_decode($body, true); + if (! is_array($json)) { + throw new LogicException('Body is json. Body: ' . $body); + } + + if (! isset($json['data']) || ! isset($json['data']['url'])) { + throw new LogicException('Body is valid json. Body: ' . $body); + } + + return $json['data']['url']; + } } diff --git a/tests/_support/AcceptanceTester.php b/tests/_support/AcceptanceTester.php index fa78f3d..314afcd 100644 --- a/tests/_support/AcceptanceTester.php +++ b/tests/_support/AcceptanceTester.php @@ -2,6 +2,7 @@ /** * Inherited Methods + * * @method void wantToTest($text) * @method void wantTo($text) * @method void execute($callable) @@ -14,12 +15,11 @@ * @method void pause() * * @SuppressWarnings(PHPMD) -*/ -class AcceptanceTester extends \Codeception\Actor -{ - use _generated\AcceptanceTesterActions; + */ +class AcceptanceTester extends \Codeception\Actor { + use _generated\AcceptanceTesterActions; - /** - * Define custom actions here - */ + /* + * Define custom actions here + */ } diff --git a/tests/_support/ApiTester.php b/tests/_support/ApiTester.php index 968d04b..d5d0bf9 100644 --- a/tests/_support/ApiTester.php +++ b/tests/_support/ApiTester.php @@ -3,6 +3,7 @@ /** * Inherited Methods + * * @method void wantToTest($text) * @method void wantTo($text) * @method void execute($callable) @@ -15,12 +16,11 @@ * @method void pause() * * @SuppressWarnings(PHPMD) -*/ -class ApiTester extends \Codeception\Actor -{ - use _generated\ApiTesterActions; + */ +class ApiTester extends \Codeception\Actor { + use _generated\ApiTesterActions; - /** - * Define custom actions here - */ + /* + * Define custom actions here + */ } diff --git a/tests/_support/Helper/Acceptance.php b/tests/_support/Helper/Acceptance.php index 65b9421..ca14117 100644 --- a/tests/_support/Helper/Acceptance.php +++ b/tests/_support/Helper/Acceptance.php @@ -1,10 +1,9 @@ getScenario()->runStep(new \Codeception\Step\Action('debugWebDriverLogs', func_get_args())); } /** @@ -33,7 +33,7 @@ public function debugWebDriverLogs($test = NULL) { * @param \Codeception\TestInterface $test * @see \Codeception\Module\WebDriver::debugWebDriverLogs() */ - public function tryToDebugWebDriverLogs($test = NULL) { + public function tryToDebugWebDriverLogs(?\Codeception\TestInterface $test = NULL) { return $this->getScenario()->runStep(new \Codeception\Step\TryTo('debugWebDriverLogs', func_get_args())); } /** @@ -45,7 +45,7 @@ public function tryToDebugWebDriverLogs($test = NULL) { * * @see \Codeception\Module\WebDriver::debugWebDriverLogs() */ - public function retryDebugWebDriverLogs($test = NULL) { + public function retryDebugWebDriverLogs(?\Codeception\TestInterface $test = NULL) { $retryNum = isset($this->retryNum) ? $this->retryNum : 1; $retryInterval = isset($this->retryInterval) ? $this->retryInterval : 200; return $this->getScenario()->runStep(new \Codeception\Step\Retry('debugWebDriverLogs', func_get_args(), $retryNum, $retryInterval)); @@ -319,7 +319,7 @@ public function retryResizeWindow($width, $height) { * @return mixed * @see \Codeception\Module\WebDriver::seeCookie() */ - public function seeCookie($cookie, $params = []) { + public function seeCookie($cookie, array $params = []) { return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeCookie', func_get_args())); } /** @@ -340,7 +340,7 @@ public function seeCookie($cookie, $params = []) { * @return mixed * @see \Codeception\Module\WebDriver::seeCookie() */ - public function canSeeCookie($cookie, $params = []) { + public function canSeeCookie($cookie, array $params = []) { return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeCookie', func_get_args())); } /** @@ -361,7 +361,7 @@ public function canSeeCookie($cookie, $params = []) { * @return mixed * @see \Codeception\Module\WebDriver::seeCookie() */ - public function tryToSeeCookie($cookie, $params = []) { + public function tryToSeeCookie($cookie, array $params = []) { return $this->getScenario()->runStep(new \Codeception\Step\TryTo('seeCookie', func_get_args())); } /** @@ -373,7 +373,7 @@ public function tryToSeeCookie($cookie, $params = []) { * * @see \Codeception\Module\WebDriver::seeCookie() */ - public function retrySeeCookie($cookie, $params = []) { + public function retrySeeCookie($cookie, array $params = []) { $retryNum = isset($this->retryNum) ? $this->retryNum : 1; $retryInterval = isset($this->retryInterval) ? $this->retryInterval : 200; return $this->getScenario()->runStep(new \Codeception\Step\Retry('seeCookie', func_get_args(), $retryNum, $retryInterval)); @@ -392,7 +392,7 @@ public function retrySeeCookie($cookie, $params = []) { * @return mixed * @see \Codeception\Module\WebDriver::dontSeeCookie() */ - public function dontSeeCookie($cookie, $params = []) { + public function dontSeeCookie($cookie, array $params = []) { return $this->getScenario()->runStep(new \Codeception\Step\Action('dontSeeCookie', func_get_args())); } /** @@ -408,7 +408,7 @@ public function dontSeeCookie($cookie, $params = []) { * @return mixed * @see \Codeception\Module\WebDriver::dontSeeCookie() */ - public function cantSeeCookie($cookie, $params = []) { + public function cantSeeCookie($cookie, array $params = []) { return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCookie', func_get_args())); } /** @@ -424,7 +424,7 @@ public function cantSeeCookie($cookie, $params = []) { * @return mixed * @see \Codeception\Module\WebDriver::dontSeeCookie() */ - public function tryToDontSeeCookie($cookie, $params = []) { + public function tryToDontSeeCookie($cookie, array $params = []) { return $this->getScenario()->runStep(new \Codeception\Step\TryTo('dontSeeCookie', func_get_args())); } /** @@ -436,7 +436,7 @@ public function tryToDontSeeCookie($cookie, $params = []) { * * @see \Codeception\Module\WebDriver::dontSeeCookie() */ - public function retryDontSeeCookie($cookie, $params = []) { + public function retryDontSeeCookie($cookie, array $params = []) { $retryNum = isset($this->retryNum) ? $this->retryNum : 1; $retryInterval = isset($this->retryInterval) ? $this->retryInterval : 200; return $this->getScenario()->runStep(new \Codeception\Step\Retry('dontSeeCookie', func_get_args(), $retryNum, $retryInterval)); @@ -462,7 +462,7 @@ public function retryDontSeeCookie($cookie, $params = []) { * @return mixed * @see \Codeception\Module\WebDriver::setCookie() */ - public function setCookie($cookie, $value, $params = [], $showDebug = true) { + public function setCookie($cookie, $value, array $params = [], $showDebug = true) { return $this->getScenario()->runStep(new \Codeception\Step\Action('setCookie', func_get_args())); } /** @@ -485,7 +485,7 @@ public function setCookie($cookie, $value, $params = [], $showDebug = true) { * @return mixed * @see \Codeception\Module\WebDriver::setCookie() */ - public function tryToSetCookie($cookie, $value, $params = [], $showDebug = true) { + public function tryToSetCookie($cookie, $value, array $params = [], $showDebug = true) { return $this->getScenario()->runStep(new \Codeception\Step\TryTo('setCookie', func_get_args())); } /** @@ -497,7 +497,7 @@ public function tryToSetCookie($cookie, $value, $params = [], $showDebug = true) * * @see \Codeception\Module\WebDriver::setCookie() */ - public function retrySetCookie($cookie, $value, $params = [], $showDebug = true) { + public function retrySetCookie($cookie, $value, array $params = [], $showDebug = true) { $retryNum = isset($this->retryNum) ? $this->retryNum : 1; $retryInterval = isset($this->retryInterval) ? $this->retryInterval : 200; return $this->getScenario()->runStep(new \Codeception\Step\Retry('setCookie', func_get_args(), $retryNum, $retryInterval)); @@ -516,7 +516,7 @@ public function retrySetCookie($cookie, $value, $params = [], $showDebug = true) * @return mixed * @see \Codeception\Module\WebDriver::resetCookie() */ - public function resetCookie($cookie, $params = []) { + public function resetCookie($cookie, array $params = []) { return $this->getScenario()->runStep(new \Codeception\Step\Action('resetCookie', func_get_args())); } /** @@ -532,7 +532,7 @@ public function resetCookie($cookie, $params = []) { * @return mixed * @see \Codeception\Module\WebDriver::resetCookie() */ - public function tryToResetCookie($cookie, $params = []) { + public function tryToResetCookie($cookie, array $params = []) { return $this->getScenario()->runStep(new \Codeception\Step\TryTo('resetCookie', func_get_args())); } /** @@ -544,7 +544,7 @@ public function tryToResetCookie($cookie, $params = []) { * * @see \Codeception\Module\WebDriver::resetCookie() */ - public function retryResetCookie($cookie, $params = []) { + public function retryResetCookie($cookie, array $params = []) { $retryNum = isset($this->retryNum) ? $this->retryNum : 1; $retryInterval = isset($this->retryInterval) ? $this->retryInterval : 200; return $this->getScenario()->runStep(new \Codeception\Step\Retry('resetCookie', func_get_args(), $retryNum, $retryInterval)); @@ -564,7 +564,7 @@ public function retryResetCookie($cookie, $params = []) { * @return mixed * @see \Codeception\Module\WebDriver::grabCookie() */ - public function grabCookie($cookie, $params = []) { + public function grabCookie($cookie, array $params = []) { return $this->getScenario()->runStep(new \Codeception\Step\Action('grabCookie', func_get_args())); } /** @@ -576,7 +576,7 @@ public function grabCookie($cookie, $params = []) { * * @see \Codeception\Module\WebDriver::grabCookie() */ - public function retryGrabCookie($cookie, $params = []) { + public function retryGrabCookie($cookie, array $params = []) { $retryNum = isset($this->retryNum) ? $this->retryNum : 1; $retryInterval = isset($this->retryInterval) ? $this->retryInterval : 200; return $this->getScenario()->runStep(new \Codeception\Step\Retry('grabCookie', func_get_args(), $retryNum, $retryInterval)); @@ -619,8 +619,8 @@ public function retryGrabPageSource() { * * ``` php * amOnUrl('http://codeception.com'); - * $I->amOnPage('/quickstart'); // moves to http://codeception.com/quickstart + * $I->amOnUrl('https://codeception.com'); + * $I->amOnPage('/quickstart'); // moves to https://codeception.com/quickstart * ?> * ``` * @see \Codeception\Module\WebDriver::amOnUrl() @@ -2274,7 +2274,7 @@ public function retryDontSeeInField($field, $value) { * @param $params * @see \Codeception\Module\WebDriver::seeInFormFields() */ - public function seeInFormFields($formSelector, $params) { + public function seeInFormFields($formSelector, array $params) { return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeInFormFields', func_get_args())); } /** @@ -2342,7 +2342,7 @@ public function seeInFormFields($formSelector, $params) { * @param $params * @see \Codeception\Module\WebDriver::seeInFormFields() */ - public function canSeeInFormFields($formSelector, $params) { + public function canSeeInFormFields($formSelector, array $params) { return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeInFormFields', func_get_args())); } /** @@ -2410,7 +2410,7 @@ public function canSeeInFormFields($formSelector, $params) { * @param $params * @see \Codeception\Module\WebDriver::seeInFormFields() */ - public function tryToSeeInFormFields($formSelector, $params) { + public function tryToSeeInFormFields($formSelector, array $params) { return $this->getScenario()->runStep(new \Codeception\Step\TryTo('seeInFormFields', func_get_args())); } /** @@ -2422,7 +2422,7 @@ public function tryToSeeInFormFields($formSelector, $params) { * * @see \Codeception\Module\WebDriver::seeInFormFields() */ - public function retrySeeInFormFields($formSelector, $params) { + public function retrySeeInFormFields($formSelector, array $params) { $retryNum = isset($this->retryNum) ? $this->retryNum : 1; $retryInterval = isset($this->retryInterval) ? $this->retryInterval : 200; return $this->getScenario()->runStep(new \Codeception\Step\Retry('seeInFormFields', func_get_args(), $retryNum, $retryInterval)); @@ -2473,7 +2473,7 @@ public function retrySeeInFormFields($formSelector, $params) { * @param $params * @see \Codeception\Module\WebDriver::dontSeeInFormFields() */ - public function dontSeeInFormFields($formSelector, $params) { + public function dontSeeInFormFields($formSelector, array $params) { return $this->getScenario()->runStep(new \Codeception\Step\Action('dontSeeInFormFields', func_get_args())); } /** @@ -2521,7 +2521,7 @@ public function dontSeeInFormFields($formSelector, $params) { * @param $params * @see \Codeception\Module\WebDriver::dontSeeInFormFields() */ - public function cantSeeInFormFields($formSelector, $params) { + public function cantSeeInFormFields($formSelector, array $params) { return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInFormFields', func_get_args())); } /** @@ -2569,7 +2569,7 @@ public function cantSeeInFormFields($formSelector, $params) { * @param $params * @see \Codeception\Module\WebDriver::dontSeeInFormFields() */ - public function tryToDontSeeInFormFields($formSelector, $params) { + public function tryToDontSeeInFormFields($formSelector, array $params) { return $this->getScenario()->runStep(new \Codeception\Step\TryTo('dontSeeInFormFields', func_get_args())); } /** @@ -2581,7 +2581,7 @@ public function tryToDontSeeInFormFields($formSelector, $params) { * * @see \Codeception\Module\WebDriver::dontSeeInFormFields() */ - public function retryDontSeeInFormFields($formSelector, $params) { + public function retryDontSeeInFormFields($formSelector, array $params) { $retryNum = isset($this->retryNum) ? $this->retryNum : 1; $retryInterval = isset($this->retryInterval) ? $this->retryInterval : 200; return $this->getScenario()->runStep(new \Codeception\Step\Retry('dontSeeInFormFields', func_get_args(), $retryNum, $retryInterval)); @@ -2830,7 +2830,7 @@ public function retryUncheckOption($option) { * ``` php * fillField("//input[@type='text']", "Hello World!"); - * $I->fillField(['name' => 'email'], 'jon@mail.com'); + * $I->fillField(['name' => 'email'], 'jon@example.com'); * ?> * ``` * @@ -2850,7 +2850,7 @@ public function fillField($field, $value) { * ``` php * fillField("//input[@type='text']", "Hello World!"); - * $I->fillField(['name' => 'email'], 'jon@mail.com'); + * $I->fillField(['name' => 'email'], 'jon@example.com'); * ?> * ``` * @@ -2926,6 +2926,79 @@ public function retryClearField($field) { } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Type in characters on active element. + * With a second parameter you can specify delay between key presses. + * + * ```php + * click('#input'); + * + * // type text in active element + * $I->type('Hello world'); + * + * // type text with a 1sec delay between chars + * $I->type('Hello World', 1); + * ``` + * + * This might be useful when you an input reacts to typing and you need to slow it down to emulate human behavior. + * For instance, this is how Credit Card fields can be filled in. + * + * @param $text + * @param $delay [sec] + * @see \Codeception\Module\WebDriver::type() + */ + public function type($text, $delay = 0) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('type', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * [!] Test won't be stopped on fail. Error won't be logged + * Type in characters on active element. + * With a second parameter you can specify delay between key presses. + * + * ```php + * click('#input'); + * + * // type text in active element + * $I->type('Hello world'); + * + * // type text with a 1sec delay between chars + * $I->type('Hello World', 1); + * ``` + * + * This might be useful when you an input reacts to typing and you need to slow it down to emulate human behavior. + * For instance, this is how Credit Card fields can be filled in. + * + * @param $text + * @param $delay [sec] + * @see \Codeception\Module\WebDriver::type() + */ + public function tryToType($text, $delay = 0) { + return $this->getScenario()->runStep(new \Codeception\Step\TryTo('type', func_get_args())); + } + /** + * [!] Method is generated. + * + * * Executes type and retries on failure. + * + * Retry number and interval set by $I->retry(); + * + * @see \Codeception\Module\WebDriver::type() + */ + public function retryType($text, $delay = 0) { + $retryNum = isset($this->retryNum) ? $this->retryNum : 1; + $retryInterval = isset($this->retryInterval) ? $this->retryInterval : 200; + return $this->getScenario()->runStep(new \Codeception\Step\Retry('type', func_get_args(), $retryNum, $retryInterval)); + } + + /** * [!] Method is generated. Documentation taken from corresponding module. * @@ -4358,7 +4431,7 @@ public function retryMoveForward() { * @param $button * @see \Codeception\Module\WebDriver::submitForm() */ - public function submitForm($selector, $params, $button = NULL) { + public function submitForm($selector, array $params, $button = NULL) { return $this->getScenario()->runStep(new \Codeception\Step\Action('submitForm', func_get_args())); } /** @@ -4524,7 +4597,7 @@ public function submitForm($selector, $params, $button = NULL) { * @param $button * @see \Codeception\Module\WebDriver::submitForm() */ - public function tryToSubmitForm($selector, $params, $button = NULL) { + public function tryToSubmitForm($selector, array $params, $button = NULL) { return $this->getScenario()->runStep(new \Codeception\Step\TryTo('submitForm', func_get_args())); } /** @@ -4536,7 +4609,7 @@ public function tryToSubmitForm($selector, $params, $button = NULL) { * * @see \Codeception\Module\WebDriver::submitForm() */ - public function retrySubmitForm($selector, $params, $button = NULL) { + public function retrySubmitForm($selector, array $params, $button = NULL) { $retryNum = isset($this->retryNum) ? $this->retryNum : 1; $retryInterval = isset($this->retryInterval) ? $this->retryInterval : 200; return $this->getScenario()->runStep(new \Codeception\Step\Retry('submitForm', func_get_args(), $retryNum, $retryInterval)); @@ -4565,7 +4638,7 @@ public function retrySubmitForm($selector, $params, $button = NULL) { * @throws \Codeception\Exception\ElementNotFound * @see \Codeception\Module\WebDriver::waitForElementChange() */ - public function waitForElementChange($element, $callback, $timeout = 30) { + public function waitForElementChange($element, \Closure $callback, $timeout = 30) { return $this->getScenario()->runStep(new \Codeception\Step\Action('waitForElementChange', func_get_args())); } @@ -4722,7 +4795,7 @@ public function wait($timeout) { * @param callable $function * @see \Codeception\Module\WebDriver::executeInSelenium() */ - public function executeInSelenium($function) { + public function executeInSelenium(\Closure $function) { return $this->getScenario()->runStep(new \Codeception\Step\Action('executeInSelenium', func_get_args())); } /** @@ -4746,7 +4819,7 @@ public function executeInSelenium($function) { * @param callable $function * @see \Codeception\Module\WebDriver::executeInSelenium() */ - public function tryToExecuteInSelenium($function) { + public function tryToExecuteInSelenium(\Closure $function) { return $this->getScenario()->runStep(new \Codeception\Step\TryTo('executeInSelenium', func_get_args())); } /** @@ -4758,7 +4831,7 @@ public function tryToExecuteInSelenium($function) { * * @see \Codeception\Module\WebDriver::executeInSelenium() */ - public function retryExecuteInSelenium($function) { + public function retryExecuteInSelenium(\Closure $function) { $retryNum = isset($this->retryNum) ? $this->retryNum : 1; $retryInterval = isset($this->retryInterval) ? $this->retryInterval : 200; return $this->getScenario()->runStep(new \Codeception\Step\Retry('executeInSelenium', func_get_args(), $retryNum, $retryInterval)); @@ -5055,7 +5128,7 @@ public function waitForJS($script, $timeout = 5) { * @return mixed * @see \Codeception\Module\WebDriver::executeJS() */ - public function executeJS($script, $arguments = []) { + public function executeJS($script, array $arguments = []) { return $this->getScenario()->runStep(new \Codeception\Step\Action('executeJS', func_get_args())); } /** @@ -5080,7 +5153,7 @@ public function executeJS($script, $arguments = []) { * @return mixed * @see \Codeception\Module\WebDriver::executeJS() */ - public function tryToExecuteJS($script, $arguments = []) { + public function tryToExecuteJS($script, array $arguments = []) { return $this->getScenario()->runStep(new \Codeception\Step\TryTo('executeJS', func_get_args())); } /** @@ -5092,7 +5165,7 @@ public function tryToExecuteJS($script, $arguments = []) { * * @see \Codeception\Module\WebDriver::executeJS() */ - public function retryExecuteJS($script, $arguments = []) { + public function retryExecuteJS($script, array $arguments = []) { $retryNum = isset($this->retryNum) ? $this->retryNum : 1; $retryInterval = isset($this->retryInterval) ? $this->retryInterval : 200; return $this->getScenario()->runStep(new \Codeception\Step\Retry('executeJS', func_get_args(), $retryNum, $retryInterval)); @@ -5120,7 +5193,7 @@ public function retryExecuteJS($script, $arguments = []) { * @return mixed * @see \Codeception\Module\WebDriver::executeAsyncJS() */ - public function executeAsyncJS($script, $arguments = []) { + public function executeAsyncJS($script, array $arguments = []) { return $this->getScenario()->runStep(new \Codeception\Step\Action('executeAsyncJS', func_get_args())); } /** @@ -5145,7 +5218,7 @@ public function executeAsyncJS($script, $arguments = []) { * @return mixed * @see \Codeception\Module\WebDriver::executeAsyncJS() */ - public function tryToExecuteAsyncJS($script, $arguments = []) { + public function tryToExecuteAsyncJS($script, array $arguments = []) { return $this->getScenario()->runStep(new \Codeception\Step\TryTo('executeAsyncJS', func_get_args())); } /** @@ -5157,7 +5230,7 @@ public function tryToExecuteAsyncJS($script, $arguments = []) { * * @see \Codeception\Module\WebDriver::executeAsyncJS() */ - public function retryExecuteAsyncJS($script, $arguments = []) { + public function retryExecuteAsyncJS($script, array $arguments = []) { $retryNum = isset($this->retryNum) ? $this->retryNum : 1; $retryInterval = isset($this->retryInterval) ? $this->retryInterval : 200; return $this->getScenario()->runStep(new \Codeception\Step\Retry('executeAsyncJS', func_get_args(), $retryNum, $retryInterval)); @@ -5927,6 +6000,69 @@ public function retryOpenNewTab() { } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks current number of opened tabs + * + * ```php + * seeNumberOfTabs(2); + * ``` + * @param $number number of tabs + * @see \Codeception\Module\WebDriver::seeNumberOfTabs() + */ + public function seeNumberOfTabs($number) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeNumberOfTabs', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * [!] Conditional Assertion: Test won't be stopped on fail + * Checks current number of opened tabs + * + * ```php + * seeNumberOfTabs(2); + * ``` + * @param $number number of tabs + * @see \Codeception\Module\WebDriver::seeNumberOfTabs() + */ + public function canSeeNumberOfTabs($number) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeNumberOfTabs', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * [!] Test won't be stopped on fail. Error won't be logged + * Checks current number of opened tabs + * + * ```php + * seeNumberOfTabs(2); + * ``` + * @param $number number of tabs + * @see \Codeception\Module\WebDriver::seeNumberOfTabs() + */ + public function tryToSeeNumberOfTabs($number) { + return $this->getScenario()->runStep(new \Codeception\Step\TryTo('seeNumberOfTabs', func_get_args())); + } + /** + * [!] Method is generated. + * + * * Executes seeNumberOfTabs and retries on failure. + * + * Retry number and interval set by $I->retry(); + * + * @see \Codeception\Module\WebDriver::seeNumberOfTabs() + */ + public function retrySeeNumberOfTabs($number) { + $retryNum = isset($this->retryNum) ? $this->retryNum : 1; + $retryInterval = isset($this->retryInterval) ? $this->retryInterval : 200; + return $this->getScenario()->runStep(new \Codeception\Step\Retry('seeNumberOfTabs', func_get_args(), $retryNum, $retryInterval)); + } + + /** * [!] Method is generated. Documentation taken from corresponding module. * diff --git a/tests/_support/_generated/ApiTesterActions.php b/tests/_support/_generated/ApiTesterActions.php index 28d82ea..655abca 100644 --- a/tests/_support/_generated/ApiTesterActions.php +++ b/tests/_support/_generated/ApiTesterActions.php @@ -1,4 +1,4 @@ - * ``` * @param array $additionalAWSConfig - * @throws ModuleException + * @throws ConfigurationException * @see \Codeception\Module\REST::amAWSAuthenticated() */ public function amAWSAuthenticated($additionalAWSConfig = []) { @@ -306,7 +306,7 @@ public function amAWSAuthenticated($additionalAWSConfig = []) { * ```php * sendPost('/message', ['subject' => 'Read this!', 'to' => 'johndoe@example.com']); + * $response = $I->sendPost('/message', ['subject' => 'Read this!', 'to' => 'johndoe@example.com']); * //simple upload method * $I->sendPost('/message/24', ['inline' => 0], ['attachmentFile' => codecept_data_dir('sample_file.pdf')]); * //uploading a file with a custom name and mime-type. This is also useful to simulate upload errors. @@ -328,7 +328,7 @@ public function amAWSAuthenticated($additionalAWSConfig = []) { * ``` * * @param $url - * @param array|\JsonSerializable $params + * @param array|string|\JsonSerializable $params * @param array $files A list of filenames or "mocks" of $_FILES (each entry being an array with the following * keys: name, type, error, size, tmp_name (pointing to the real file path). Each key works * as the "name" attribute of a file input field. @@ -381,6 +381,14 @@ public function sendOptions($url, $params = []) { * * Sends a GET request to given uri. * + * ```php + * sendGet('/users'); + * + * // send get with query params + * $I->sendGet('/orders', ['id' => 1]) + * ``` + * * @param $url * @param array $params * @part json @@ -397,8 +405,13 @@ public function sendGet($url, $params = []) { * * Sends PUT request to given uri. * + * ```php + * sendPut('/message/1', ['subject' => 'Read this!']); + * ``` + * * @param $url - * @param array $params + * @param array|string|\JsonSerializable $params * @param array $files * @part json * @part xml @@ -414,8 +427,13 @@ public function sendPut($url, $params = [], $files = []) { * * Sends PATCH request to given uri. * + * ```php + * sendPatch('/message/1', ['subject' => 'Read this!']); + * ``` + * * @param $url - * @param array $params + * @param array|string|\JsonSerializable $params * @param array $files * @part json * @part xml @@ -430,6 +448,12 @@ public function sendPatch($url, $params = [], $files = []) { * [!] Method is generated. Documentation taken from corresponding module. * * Sends DELETE request to given uri. + * + * ```php + * sendDelete('/message/1'); + * ``` + * * @param $url * @param array $params @@ -443,6 +467,24 @@ public function sendDelete($url, $params = [], $files = []) { } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Sends a HTTP request. + * + * @param $method + * @param $url + * @param array|string|\JsonSerializable $params + * @param array $files + * @part json + * @part xml + * @see \Codeception\Module\REST::send() + */ + public function send($method, $url, $params = [], $files = []) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('send', func_get_args())); + } + + /** * [!] Method is generated. Documentation taken from corresponding module. * @@ -458,7 +500,7 @@ public function sendDelete($url, $params = [], $files = []) { * @part xml * @see \Codeception\Module\REST::sendLink() */ - public function sendLink($url, $linkEntries) { + public function sendLink($url, array $linkEntries) { return $this->getScenario()->runStep(new \Codeception\Step\Action('sendLink', func_get_args())); } @@ -476,7 +518,7 @@ public function sendLink($url, $linkEntries) { * @part xml * @see \Codeception\Module\REST::sendUnlink() */ - public function sendUnlink($url, $linkEntries) { + public function sendUnlink($url, array $linkEntries) { return $this->getScenario()->runStep(new \Codeception\Step\Action('sendUnlink', func_get_args())); } @@ -750,7 +792,6 @@ public function canSeeResponseIsValidOnJsonSchema($schemaFilename) { * @return string * @part json * @part xml - * @version 1.1 * @see \Codeception\Module\REST::grabResponse() */ public function grabResponse() { @@ -761,13 +802,8 @@ public function grabResponse() { /** * [!] Method is generated. Documentation taken from corresponding module. * - * Returns data from the current JSON response using [JSONPath](http://goessner.net/articles/JsonPath/) as selector. - * JsonPath is XPath equivalent for querying Json structures. - * Try your JsonPath expressions [online](http://jsonpath.curiousconcept.com/). + * See [#jsonpath](#jsonpath) for general info on JSONPath. * Even for a single value an array is returned. - * - * This method **require [`flow/jsonpath` > 0.2](https://github.com/FlowCommunications/JSONPath/) library to be installed**. - * * Example: * * ``` php @@ -782,7 +818,6 @@ public function grabResponse() { * @return array Array of matching items * @throws \Exception * @part json - * @version 2.0.9 * @see \Codeception\Module\REST::grabDataFromResponseByJsonPath() */ public function grabDataFromResponseByJsonPath($jsonPath) { @@ -831,7 +866,6 @@ public function grabDataFromResponseByJsonPath($jsonPath) { * ``` * @param string $xpath * @part json - * @version 2.0.9 * @see \Codeception\Module\REST::seeResponseJsonMatchesXpath() */ public function seeResponseJsonMatchesXpath($xpath) { @@ -879,7 +913,6 @@ public function seeResponseJsonMatchesXpath($xpath) { * ``` * @param string $xpath * @part json - * @version 2.0.9 * @see \Codeception\Module\REST::seeResponseJsonMatchesXpath() */ public function canSeeResponseJsonMatchesXpath($xpath) { @@ -917,12 +950,8 @@ public function cantSeeResponseJsonMatchesXpath($xpath) { /** * [!] Method is generated. Documentation taken from corresponding module. * - * Checks if json structure in response matches [JsonPath](http://goessner.net/articles/JsonPath/). - * JsonPath is XPath equivalent for querying Json structures. - * Try your JsonPath expressions [online](http://jsonpath.curiousconcept.com/). - * This assertion allows you to check the structure of response json. - * - * This method **require [`flow/jsonpath` > 0.2](https://github.com/FlowCommunications/JSONPath/) library to be installed**. + * See [#jsonpath](#jsonpath) for general info on JSONPath. + * Checks if JSON structure in response matches JSONPath. * * ```json * { "store": { @@ -959,7 +988,6 @@ public function cantSeeResponseJsonMatchesXpath($xpath) { * * @param string $jsonPath * @part json - * @version 2.0.9 * @see \Codeception\Module\REST::seeResponseJsonMatchesJsonPath() */ public function seeResponseJsonMatchesJsonPath($jsonPath) { @@ -969,12 +997,8 @@ public function seeResponseJsonMatchesJsonPath($jsonPath) { * [!] Method is generated. Documentation taken from corresponding module. * * [!] Conditional Assertion: Test won't be stopped on fail - * Checks if json structure in response matches [JsonPath](http://goessner.net/articles/JsonPath/). - * JsonPath is XPath equivalent for querying Json structures. - * Try your JsonPath expressions [online](http://jsonpath.curiousconcept.com/). - * This assertion allows you to check the structure of response json. - * - * This method **require [`flow/jsonpath` > 0.2](https://github.com/FlowCommunications/JSONPath/) library to be installed**. + * See [#jsonpath](#jsonpath) for general info on JSONPath. + * Checks if JSON structure in response matches JSONPath. * * ```json * { "store": { @@ -1011,7 +1035,6 @@ public function seeResponseJsonMatchesJsonPath($jsonPath) { * * @param string $jsonPath * @part json - * @version 2.0.9 * @see \Codeception\Module\REST::seeResponseJsonMatchesJsonPath() */ public function canSeeResponseJsonMatchesJsonPath($jsonPath) { @@ -1022,7 +1045,8 @@ public function canSeeResponseJsonMatchesJsonPath($jsonPath) { /** * [!] Method is generated. Documentation taken from corresponding module. * - * Opposite to seeResponseJsonMatchesJsonPath + * See [#jsonpath](#jsonpath) for general info on JSONPath. + * Opposite to [`seeResponseJsonMatchesJsonPath()`](#seeResponseJsonMatchesJsonPath) * * @param string $jsonPath * @part json @@ -1035,7 +1059,8 @@ public function dontSeeResponseJsonMatchesJsonPath($jsonPath) { * [!] Method is generated. Documentation taken from corresponding module. * * [!] Conditional Assertion: Test won't be stopped on fail - * Opposite to seeResponseJsonMatchesJsonPath + * See [#jsonpath](#jsonpath) for general info on JSONPath. + * Opposite to [`seeResponseJsonMatchesJsonPath()`](#seeResponseJsonMatchesJsonPath) * * @param string $jsonPath * @part json @@ -1156,10 +1181,9 @@ public function cantSeeResponseContainsJson($json = []) { * @param array $jsonType * @param string $jsonPath * @see JsonType - * @version 2.1.3 * @see \Codeception\Module\REST::seeResponseMatchesJsonType() */ - public function seeResponseMatchesJsonType($jsonType, $jsonPath = NULL) { + public function seeResponseMatchesJsonType(array $jsonType, $jsonPath = NULL) { return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeResponseMatchesJsonType', func_get_args())); } /** @@ -1246,10 +1270,9 @@ public function seeResponseMatchesJsonType($jsonType, $jsonPath = NULL) { * @param array $jsonType * @param string $jsonPath * @see JsonType - * @version 2.1.3 * @see \Codeception\Module\REST::seeResponseMatchesJsonType() */ - public function canSeeResponseMatchesJsonType($jsonType, $jsonPath = NULL) { + public function canSeeResponseMatchesJsonType(array $jsonType, $jsonPath = NULL) { return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeResponseMatchesJsonType', func_get_args())); } @@ -1260,13 +1283,12 @@ public function canSeeResponseMatchesJsonType($jsonType, $jsonPath = NULL) { * Opposite to `seeResponseMatchesJsonType`. * * @part json - * @param $jsonType jsonType structure - * @param null $jsonPath optionally set specific path to structure with JsonPath + * @param array $jsonType JsonType structure + * @param string $jsonPath * @see seeResponseMatchesJsonType - * @version 2.1.3 * @see \Codeception\Module\REST::dontSeeResponseMatchesJsonType() */ - public function dontSeeResponseMatchesJsonType($jsonType, $jsonPath = NULL) { + public function dontSeeResponseMatchesJsonType(array $jsonType, $jsonPath = NULL) { return $this->getScenario()->runStep(new \Codeception\Step\Action('dontSeeResponseMatchesJsonType', func_get_args())); } /** @@ -1276,13 +1298,12 @@ public function dontSeeResponseMatchesJsonType($jsonType, $jsonPath = NULL) { * Opposite to `seeResponseMatchesJsonType`. * * @part json - * @param $jsonType jsonType structure - * @param null $jsonPath optionally set specific path to structure with JsonPath + * @param array $jsonType JsonType structure + * @param string $jsonPath * @see seeResponseMatchesJsonType - * @version 2.1.3 * @see \Codeception\Module\REST::dontSeeResponseMatchesJsonType() */ - public function cantSeeResponseMatchesJsonType($jsonType, $jsonPath = NULL) { + public function cantSeeResponseMatchesJsonType(array $jsonType, $jsonPath = NULL) { return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeResponseMatchesJsonType', func_get_args())); } @@ -1820,8 +1841,8 @@ public function cantSeeXmlResponseIncludes($xml) { * ?> * ``` * - * @param $hash the hashed data response expected - * @param $algo the hash algorithm to use. Default md5. + * @param string $hash the hashed data response expected + * @param string $algo the hash algorithm to use. Default md5. * @part json * @part xml * @see \Codeception\Module\REST::seeBinaryResponseEquals() @@ -1862,8 +1883,8 @@ public function seeBinaryResponseEquals($hash, $algo = "md5") { * ?> * ``` * - * @param $hash the hashed data response expected - * @param $algo the hash algorithm to use. Default md5. + * @param string $hash the hashed data response expected + * @param string $algo the hash algorithm to use. Default md5. * @part json * @part xml * @see \Codeception\Module\REST::seeBinaryResponseEquals() @@ -1885,8 +1906,8 @@ public function canSeeBinaryResponseEquals($hash, $algo = "md5") { * ``` * Opposite to `seeBinaryResponseEquals` * - * @param $hash the hashed data response expected - * @param $algo the hash algorithm to use. Default md5. + * @param string $hash the hashed data response expected + * @param string $algo the hash algorithm to use. Default md5. * @part json * @part xml * @see \Codeception\Module\REST::dontSeeBinaryResponseEquals() @@ -1907,8 +1928,8 @@ public function dontSeeBinaryResponseEquals($hash, $algo = "md5") { * ``` * Opposite to `seeBinaryResponseEquals` * - * @param $hash the hashed data response expected - * @param $algo the hash algorithm to use. Default md5. + * @param string $hash the hashed data response expected + * @param string $algo the hash algorithm to use. Default md5. * @part json * @part xml * @see \Codeception\Module\REST::dontSeeBinaryResponseEquals() @@ -1967,7 +1988,7 @@ public function startFollowingRedirects() { * ``` * @see \Codeception\Module\REST::setServerParameters() */ - public function setServerParameters($params) { + public function setServerParameters(array $params) { return $this->getScenario()->runStep(new \Codeception\Step\Action('setServerParameters', func_get_args())); } diff --git a/tests/acceptance/LoginCest.php b/tests/acceptance/LoginCest.php index bb8f3b7..9a4f420 100644 --- a/tests/acceptance/LoginCest.php +++ b/tests/acceptance/LoginCest.php @@ -1,10 +1,8 @@ amOnPage('/'); - $I->see('_'); - } +class LoginCest { + public function loginSuccessfully(AcceptanceTester $I) { + $I->amOnPage('/'); + $I->see('_'); + } } diff --git a/tests/api/ApiCest.php b/tests/api/ApiCest.php index 8fa4c07..c3c50d7 100644 --- a/tests/api/ApiCest.php +++ b/tests/api/ApiCest.php @@ -2,11 +2,9 @@ use Codeception\Util\HttpCode; -class ApiCest -{ - public function openHome(ApiTester $I) - { - $I->sendGet('/'); - $I->seeResponseCodeIs(HttpCode::OK); - } +class ApiCest { + public function openHome(ApiTester $I) { + $I->sendGet('/'); + $I->seeResponseCodeIs(HttpCode::OK); + } } diff --git a/tests/unit/GitHubReporterTest.php b/tests/unit/GitHubReporterTest.php index 7af942b..b25e0d6 100644 --- a/tests/unit/GitHubReporterTest.php +++ b/tests/unit/GitHubReporterTest.php @@ -5,21 +5,17 @@ use Like\Codeception\GitHubReporter; use PHPUnit\Framework\TestCase; -class GitHubReporterTest extends TestCase -{ - public function testInstance() - { - $instance = new GitHubReporter([], []); - $this->assertInstanceOf(GitHubReporter::class, $instance); - } +class GitHubReporterTest extends TestCase { + public function testInstance(): void { + $instance = new GitHubReporter([], []); + $this->assertInstanceOf(GitHubReporter::class, $instance); + } - public function testAssertFalse() - { - $this->assertTrue(false); - } + public function testAssertFalse(): void { + $this->assertTrue(false); + } - public function testError() - { - $this->assertTrue(); - } + public function testError(): void { + $this->assertTrue(); + } }
' . join('', $suiteTests) . '