diff --git a/composer.json b/composer.json index 6b2e479c..ab41f20c 100644 --- a/composer.json +++ b/composer.json @@ -7,12 +7,12 @@ "require": { "php": ">=8.0", - "behat/behat": "^3.0.13", - "friends-of-behat/mink-extension": "^2.3.1", + "behat/behat": "^4.0", + "friends-of-behat/mink-extension": "^3.0", "justinrainbow/json-schema": "^5.0|^6.0", - "symfony/property-access": "^2.3|^3.0|^4.0|^5.0|^6.0|^7.0", - "symfony/http-foundation": "^2.3|^3.0|^4.0|^5.0|^6.0|^7.0", - "symfony/dom-crawler": "^2.4|^3.0|^4.0|^5.0|^6.0|^7.0" + "symfony/property-access": "^2.3|^3.0|^4.0|^5.0|^6.0|^7.0|^8.0", + "symfony/http-foundation": "^2.3|^3.0|^4.0|^5.0|^6.0|^7.0|^8.0", + "symfony/dom-crawler": "^2.4|^3.0|^4.0|^5.0|^6.0|^7.0|^8.0" }, "require-dev": { diff --git a/src/Context/BrowserContext.php b/src/Context/BrowserContext.php index 07ef6c42..398b41fb 100644 --- a/src/Context/BrowserContext.php +++ b/src/Context/BrowserContext.php @@ -4,9 +4,14 @@ use Behat\Behat\Tester\Exception\PendingException; use Behat\Gherkin\Node\TableNode; +use Behat\Hook\AfterScenario; +use Behat\Hook\BeforeScenario; use Behat\Mink\Exception\ElementNotFoundException; use Behat\Mink\Exception\ExpectationException; use Behat\Mink\Exception\ResponseTextException; +use Behat\Step\Given; +use Behat\Step\Then; +use Behat\Step\When; use WebDriver\Exception\StaleElementReference; class BrowserContext extends BaseContext @@ -20,9 +25,7 @@ public function __construct($timeout = 1) $this->timeout = $timeout; } - /** - * @AfterScenario - */ + #[AfterScenario] public function closeBrowser(): void { if ($this->getMink()->isSessionStarted()) { @@ -30,11 +33,8 @@ public function closeBrowser(): void } } - /** - * @BeforeScenario - * - * @When (I )start timing now - */ + #[BeforeScenario] + #[When('(I )start timing now')] public function startTimer(): void { $this->timerStartedAt = time(); @@ -42,9 +42,8 @@ public function startTimer(): void /** * Set login / password for next HTTP authentication. - * - * @When (I )set basic authentication with :user and :password */ + #[When('(I )set basic authentication with :user and :password')] public function iSetBasicAuthenticationWithAnd($user, $password): void { $this->getSession()->setBasicAuth($user, $password); @@ -52,9 +51,8 @@ public function iSetBasicAuthenticationWithAnd($user, $password): void /** * Open url with various parameters. - * - * @Given (I )am on url composed by: */ + #[Given('(I )am on url composed by:')] public function iAmOnUrlComposedBy(TableNode $tableNode) { $url = ''; @@ -68,9 +66,8 @@ public function iAmOnUrlComposedBy(TableNode $tableNode) /** * Clicks on the nth CSS element. - * - * @When (I )click on the :index :element element */ + #[When('(I )click on the :index :element element')] public function iClickOnTheNthElement($index, $element): void { $node = $this->findElement('css', $element, $index); @@ -79,9 +76,8 @@ public function iClickOnTheNthElement($index, $element): void /** * Click on the nth specified link. - * - * @When (I )follow the :index :link link */ + #[When('(I )follow the :index :link link')] public function iFollowTheNthLink($index, $link): void { $node = $this->findElement('named', ['link', $link], $index); @@ -90,9 +86,8 @@ public function iFollowTheNthLink($index, $link): void /** * Presses the nth specified button. - * - * @When (I )press the :index :button button */ + #[When('(I )press the :index :button button')] public function pressTheNthButton($index, $button): void { $node = $this->findElement('named', ['button', $button], $index); @@ -101,9 +96,8 @@ public function pressTheNthButton($index, $button): void /** * Fills in form field with current date. - * - * @When (I )fill in :field with the current date */ + #[When('(I )fill in :field with the current date')] public function iFillInWithTheCurrentDate($field) { return $this->iFillInWithTheCurrentDateAndModifier($field, 'now'); @@ -111,9 +105,8 @@ public function iFillInWithTheCurrentDate($field) /** * Fills in form field with current date and strtotime modifier. - * - * @When (I )fill in :field with the current date and modifier :modifier */ + #[When('(I )fill in :field with the current date and modifier :modifier')] public function iFillInWithTheCurrentDateAndModifier($field, $modifier) { return $this->getMinkContext() @@ -122,9 +115,8 @@ public function iFillInWithTheCurrentDateAndModifier($field, $modifier) /** * Mouse over a CSS element. - * - * @When (I )hover :element */ + #[When('(I )hover :element')] public function iHoverIShouldSeeIn($element): void { $node = $this->getSession()->getPage()->find('css', $element); @@ -136,9 +128,8 @@ public function iHoverIShouldSeeIn($element): void /** * Save value of the field in parameters array. - * - * @When (I )save the value of :field in the :parameter parameter */ + #[When('(I )save the value of :field in the :parameter parameter')] public function iSaveTheValueOfInTheParameter($field, $parameter): void { $field = str_replace('\\"', '"', $field); @@ -152,9 +143,8 @@ public function iSaveTheValueOfInTheParameter($field, $parameter): void /** * Checks, that the page should contains specified text after given timeout. - * - * @Then (I )wait :count second(s) until I see :text */ + #[Then('(I )wait :count second(s) until I see :text')] public function iWaitSecondsUntilISee($count, $text): void { $this->iWaitSecondsUntilISeeInTheElement($count, $text, 'html'); @@ -162,9 +152,8 @@ public function iWaitSecondsUntilISee($count, $text): void /** * Checks, that the page should not contain specified text before given timeout. - * - * @Then (I )should not see :text within :count second(s) */ + #[Then('(I )should not see :text within :count second(s)')] public function iDontSeeInSeconds($count, $text): void { $caught = false; @@ -179,9 +168,8 @@ public function iDontSeeInSeconds($count, $text): void /** * Checks, that the page should contains specified text after timeout. - * - * @Then (I )wait until I see :text */ + #[Then('(I )wait until I see :text')] public function iWaitUntilISee($text): void { $this->iWaitSecondsUntilISee($this->timeout, $text); @@ -189,9 +177,8 @@ public function iWaitUntilISee($text): void /** * Checks, that the element contains specified text after timeout. - * - * @Then (I )wait :count second(s) until I see :text in the :element element */ + #[Then('(I )wait :count second(s) until I see :text in the :element element')] public function iWaitSecondsUntilISeeInTheElement($count, $text, $element): void { $startTime = time(); @@ -219,9 +206,7 @@ public function iWaitSecondsUntilISeeInTheElement($count, $text, $element): void $this->assertContains($expected, $node->getText(), $message); } - /** - * @Then (I )wait :count second(s) - */ + #[Then('(I )wait :count second(s)')] public function iWaitSeconds($count): void { usleep((int) ($count * 1000000)); @@ -229,9 +214,8 @@ public function iWaitSeconds($count): void /** * Checks, that the element contains specified text after timeout. - * - * @Then (I )wait until I see :text in the :element element */ + #[Then('(I )wait until I see :text in the :element element')] public function iWaitUntilISeeInTheElement($text, $element): void { $this->iWaitSecondsUntilISeeInTheElement($this->timeout, $text, $element); @@ -239,9 +223,8 @@ public function iWaitUntilISeeInTheElement($text, $element): void /** * Checks, that the page should contains specified element after timeout. - * - * @Then (I )wait for :element element */ + #[Then('(I )wait for :element element')] public function iWaitForElement($element): void { $this->iWaitSecondsForElement($this->timeout, $element); @@ -249,9 +232,8 @@ public function iWaitForElement($element): void /** * Wait for a element. - * - * @Then (I )wait :count second(s) for :element element */ + #[Then('(I )wait :count second(s) for :element element')] public function iWaitSecondsForElement($count, $element): void { $found = false; @@ -275,9 +257,7 @@ public function iWaitSecondsForElement($count, $element): void } } - /** - * @Then /^(?:|I )should see (?P\d+) "(?P[^"]*)" in the (?P\d+)(?:st|nd|rd|th) "(?P[^"]*)"$/ - */ + #[Then('/^(?:|I )should see (?P\d+) "(?P[^"]*)" in the (?P\d+)(?:st|nd|rd|th) "(?P[^"]*)"$/')] public function iShouldSeeNElementInTheNthParent($count, $element, $index, $parent): void { $actual = $this->countElements($element, $index, $parent); @@ -286,9 +266,7 @@ public function iShouldSeeNElementInTheNthParent($count, $element, $index, $pare } } - /** - * @Then (I )should see less than :count :element in the :index :parent - */ + #[Then('(I )should see less than :count :element in the :index :parent')] public function iShouldSeeLessThanNElementInTheNthParent($count, $element, $index, $parent): void { $actual = $this->countElements($element, $index, $parent); @@ -297,9 +275,7 @@ public function iShouldSeeLessThanNElementInTheNthParent($count, $element, $inde } } - /** - * @Then (I )should see more than :count :element in the :index :parent - */ + #[Then('(I )should see more than :count :element in the :index :parent')] public function iShouldSeeMoreThanNElementInTheNthParent($count, $element, $index, $parent): void { $actual = $this->countElements($element, $index, $parent); @@ -310,9 +286,8 @@ public function iShouldSeeMoreThanNElementInTheNthParent($count, $element, $inde /** * Checks, that element with given CSS is enabled. - * - * @Then the element :element should be enabled */ + #[Then('the element :element should be enabled')] public function theElementShouldBeEnabled($element): void { $node = $this->getSession()->getPage()->find('css', $element); @@ -327,9 +302,8 @@ public function theElementShouldBeEnabled($element): void /** * Checks, that element with given CSS is disabled. - * - * @Then the element :element should be disabled */ + #[Then('the element :element should be disabled')] public function theElementShouldBeDisabled($element): void { $this->not(function () use ($element): void { @@ -339,9 +313,8 @@ public function theElementShouldBeDisabled($element): void /** * Checks, that given select box contains the specified option. - * - * @Then the :select select box should contain :option */ + #[Then('the :select select box should contain :option')] public function theSelectBoxShouldContain($select, $option): void { $select = str_replace('\\"', '"', $select); @@ -359,9 +332,8 @@ public function theSelectBoxShouldContain($select, $option): void /** * Checks, that given select box does not contain the specified option. - * - * @Then the :select select box should not contain :option */ + #[Then('the :select select box should not contain :option')] public function theSelectBoxShouldNotContain($select, $option): void { $this->not(function () use ($select, $option): void { @@ -371,9 +343,8 @@ public function theSelectBoxShouldNotContain($select, $option): void /** * Checks, that the specified CSS element is visible. - * - * @Then the :element element should be visible */ + #[Then('the :element element should be visible')] public function theElementShouldBeVisible($element): void { $displayedNode = $this->getSession()->getPage()->find('css', $element); @@ -387,9 +358,8 @@ public function theElementShouldBeVisible($element): void /** * Checks, that the specified CSS element is not visible. - * - * @Then the :element element should not be visible */ + #[Then('the :element element should not be visible')] public function theElementShouldNotBeVisible($element): void { $exception = new \Exception("The element '$element' is visible"); @@ -401,10 +371,9 @@ public function theElementShouldNotBeVisible($element): void /** * Select a frame by its name or ID. - * - * @When (I )switch to iframe :name - * @When (I )switch to frame :name */ + #[When('(I )switch to iframe :name')] + #[When('(I )switch to frame :name')] public function switchToIFrame($name): void { $this->getSession()->switchToIFrame($name); @@ -412,9 +381,8 @@ public function switchToIFrame($name): void /** * Go back to main document frame. - * - * @When (I )switch to main frame */ + #[When('(I )switch to main frame')] public function switchToMainFrame(): void { $this->getSession()->switchToIFrame(); @@ -422,10 +390,9 @@ public function switchToMainFrame(): void /** * test time from when the scenario started. - * - * @Then (the )total elapsed time should be :comparison than :expected seconds - * @Then (the )total elapsed time should be :comparison to :expected seconds */ + #[Then('(the )total elapsed time should be :comparison than :expected seconds')] + #[Then('(the )total elapsed time should be :comparison to :expected seconds')] public function elapsedTime($comparison, $expected): void { $elapsed = time() - $this->timerStartedAt; diff --git a/src/Context/ContextClass/ClassResolver.php b/src/Context/ContextClass/ClassResolver.php index 79c4463c..8bcb6926 100644 --- a/src/Context/ContextClass/ClassResolver.php +++ b/src/Context/ContextClass/ClassResolver.php @@ -6,12 +6,12 @@ class ClassResolver implements BaseClassResolver { - public function supportsClass($contextClass) + public function supportsClass($contextClass): bool { return str_starts_with($contextClass, 'behatch:context:'); } - public function resolveClass($contextClass) + public function resolveClass($contextClass): string { $className = preg_replace_callback('/(^\w|:\w)/', function ($matches) { return str_replace(':', '\\', strtoupper($matches[0])); diff --git a/src/Context/DebugContext.php b/src/Context/DebugContext.php index d13e62e4..8c489bbe 100644 --- a/src/Context/DebugContext.php +++ b/src/Context/DebugContext.php @@ -4,7 +4,10 @@ use Behat\Behat\Hook\Scope\AfterStepScope; use Behat\Gherkin\Node\StepNode; +use Behat\Hook\AfterStep; use Behat\Mink\Exception\UnsupportedDriverActionException; +use Behat\Step\Then; +use Behat\Step\When; class DebugContext extends BaseContext { @@ -20,9 +23,8 @@ public function __construct($screenshotDir = '.') /** * Pauses the scenario until the user presses a key. Useful when debugging a scenario. - * - * @Then (I )put a breakpoint */ + #[Then('(I )put a breakpoint')] public function iPutABreakpoint(): void { fwrite(\STDOUT, "\033[s \033[93m[Breakpoint] Press \033[1;93m[RETURN]\033[0;93m to continue...\033[0m"); @@ -33,18 +35,15 @@ public function iPutABreakpoint(): void /** * Saving a screenshot. - * - * @When (I )save a screenshot in :filename */ + #[When('(I )save a screenshot in :filename')] public function iSaveAScreenshotIn($filename): void { sleep(1); $this->saveScreenshot($filename, $this->screenshotDir); } - /** - * @AfterStep - */ + #[AfterStep] public function failScreenshots(AfterStepScope $scope): void { if ($scope->getTestResult()->isPassed()) { diff --git a/src/Context/JsonContext.php b/src/Context/JsonContext.php index c808c32d..f7c7b8eb 100644 --- a/src/Context/JsonContext.php +++ b/src/Context/JsonContext.php @@ -4,6 +4,7 @@ use Behat\Gherkin\Node\PyStringNode; use Behat\Gherkin\Node\TableNode; +use Behat\Step\Then; use Behatch\HttpCall\HttpCallResultPool; use Behatch\Json\Json; use Behatch\Json\JsonInspector; @@ -23,9 +24,8 @@ public function __construct(HttpCallResultPool $httpCallResultPool, $evaluationM /** * Checks, that the response is correct JSON. - * - * @Then the response should be in JSON */ + #[Then('the response should be in JSON')] public function theResponseShouldBeInJson(): void { $this->getJson(); @@ -33,9 +33,8 @@ public function theResponseShouldBeInJson(): void /** * Checks, that the response is not correct JSON. - * - * @Then the response should not be in JSON */ + #[Then('the response should not be in JSON')] public function theResponseShouldNotBeInJson(): void { $this->not(fn () => $this->theResponseShouldBeInJson(), 'The response is in JSON'); @@ -43,9 +42,8 @@ public function theResponseShouldNotBeInJson(): void /** * Checks, that given JSON node is equal to given value. - * - * @Then the JSON node :node should be equal to :expected */ + #[Then('the JSON node :node should be equal to :expected')] public function theJsonNodeShouldBeEqualTo($node, $expected): void { $json = $this->getJson(); @@ -61,9 +59,8 @@ public function theJsonNodeShouldBeEqualTo($node, $expected): void /** * Checks, that given JSON nodes are equal to givens values. - * - * @Then the JSON nodes should be equal to: */ + #[Then('the JSON nodes should be equal to:')] public function theJsonNodesShouldBeEqualTo(TableNode $nodes): void { $json = $this->getJson(); @@ -86,9 +83,8 @@ public function theJsonNodesShouldBeEqualTo(TableNode $nodes): void /** * Checks, that given JSON node matches given pattern. - * - * @Then the JSON node :node should match :pattern */ + #[Then('the JSON node :node should match :pattern')] public function theJsonNodeShouldMatch($node, $pattern): void { $json = $this->getJson(); @@ -102,9 +98,8 @@ public function theJsonNodeShouldMatch($node, $pattern): void /** * Checks, that given JSON node is null. - * - * @Then the JSON node :node should be null */ + #[Then('the JSON node :node should be null')] public function theJsonNodeShouldBeNull($node): void { $json = $this->getJson(); @@ -118,9 +113,8 @@ public function theJsonNodeShouldBeNull($node): void /** * Checks, that given JSON node is not null. - * - * @Then the JSON node :node should not be null */ + #[Then('the JSON node :node should not be null')] public function theJsonNodeShouldNotBeNull($node): void { $json = $this->getJson(); @@ -134,9 +128,8 @@ public function theJsonNodeShouldNotBeNull($node): void /** * Checks, that given JSON node is true. - * - * @Then the JSON node :node should be true */ + #[Then('the JSON node :node should be true')] public function theJsonNodeShouldBeTrue($node): void { $json = $this->getJson(); @@ -150,9 +143,8 @@ public function theJsonNodeShouldBeTrue($node): void /** * Checks, that given JSON node is false. - * - * @Then the JSON node :node should be false */ + #[Then('the JSON node :node should be false')] public function theJsonNodeShouldBeFalse($node): void { $json = $this->getJson(); @@ -166,9 +158,8 @@ public function theJsonNodeShouldBeFalse($node): void /** * Checks, that given JSON node is equal to the given string. - * - * @Then the JSON node :node should be equal to the string :expected */ + #[Then('the JSON node :node should be equal to the string :expected')] public function theJsonNodeShouldBeEqualToTheString($node, $expected): void { $json = $this->getJson(); @@ -182,9 +173,8 @@ public function theJsonNodeShouldBeEqualToTheString($node, $expected): void /** * Checks, that given JSON node is equal to the given number. - * - * @Then the JSON node :node should be equal to the number :number */ + #[Then('the JSON node :node should be equal to the number :number')] public function theJsonNodeShouldBeEqualToTheNumber($node, $number): void { $json = $this->getJson(); @@ -198,10 +188,9 @@ public function theJsonNodeShouldBeEqualToTheNumber($node, $number): void /** * Checks, that given JSON node has N element(s). - * - * @Then the JSON node :node should have :count element(s) */ - public function theJsonNodeShouldHaveElements($node, $count): void + #[Then('the JSON node :node should have :count element(s)')] + public function theJsonNodeShouldHaveElements($node, int $count): void { $json = $this->getJson(); @@ -212,9 +201,8 @@ public function theJsonNodeShouldHaveElements($node, $count): void /** * Checks, that given JSON node contains given value. - * - * @Then the JSON node :node should contain :text */ + #[Then('the JSON node :node should contain :text')] public function theJsonNodeShouldContain($node, $text): void { $json = $this->getJson(); @@ -226,9 +214,8 @@ public function theJsonNodeShouldContain($node, $text): void /** * Checks, that given JSON nodes contains values. - * - * @Then the JSON nodes should contain: */ + #[Then('the JSON nodes should contain:')] public function theJsonNodesShouldContain(TableNode $nodes): void { foreach ($nodes->getRowsHash() as $node => $text) { @@ -238,9 +225,8 @@ public function theJsonNodesShouldContain(TableNode $nodes): void /** * Checks, that given JSON node does not contain given value. - * - * @Then the JSON node :node should not contain :text */ + #[Then('the JSON node :node should not contain :text')] public function theJsonNodeShouldNotContain($node, $text): void { $json = $this->getJson(); @@ -252,9 +238,8 @@ public function theJsonNodeShouldNotContain($node, $text): void /** * Checks, that given JSON nodes does not contain given value. - * - * @Then the JSON nodes should not contain: */ + #[Then('the JSON nodes should not contain:')] public function theJsonNodesShouldNotContain(TableNode $nodes): void { foreach ($nodes->getRowsHash() as $node => $text) { @@ -264,9 +249,8 @@ public function theJsonNodesShouldNotContain(TableNode $nodes): void /** * Checks, that given JSON node exist. - * - * @Then the JSON node :name should exist */ + #[Then('the JSON node :name should exist')] public function theJsonNodeShouldExist($name) { $json = $this->getJson(); @@ -282,9 +266,8 @@ public function theJsonNodeShouldExist($name) /** * Checks, that given JSON node does not exist. - * - * @Then the JSON node :name should not exist */ + #[Then('the JSON node :name should not exist')] public function theJsonNodeShouldNotExist($name): void { $this->not(function () use ($name) { @@ -292,9 +275,7 @@ public function theJsonNodeShouldNotExist($name): void }, "The node '$name' exists."); } - /** - * @Then the JSON should be valid according to this schema: - */ + #[Then('the JSON should be valid according to this schema:')] public function theJsonShouldBeValidAccordingToThisSchema(PyStringNode $schema): void { $this->inspector->validate( @@ -303,17 +284,13 @@ public function theJsonShouldBeValidAccordingToThisSchema(PyStringNode $schema): ); } - /** - * @Then the JSON should be invalid according to this schema: - */ + #[Then('the JSON should be invalid according to this schema:')] public function theJsonShouldBeInvalidAccordingToThisSchema(PyStringNode $schema): void { $this->not(fn () => $this->theJsonShouldBeValidAccordingToThisSchema($schema), 'Expected to receive invalid json, got valid one'); } - /** - * @Then the JSON should be valid according to the schema :filename - */ + #[Then('the JSON should be valid according to the schema :filename')] public function theJsonShouldBeValidAccordingToTheSchema($filename): void { $this->checkSchemaFile($filename); @@ -327,9 +304,7 @@ public function theJsonShouldBeValidAccordingToTheSchema($filename): void ); } - /** - * @Then the JSON should be invalid according to the schema :filename - */ + #[Then('the JSON should be invalid according to the schema :filename')] public function theJsonShouldBeInvalidAccordingToTheSchema($filename): void { $this->checkSchemaFile($filename); @@ -337,9 +312,7 @@ public function theJsonShouldBeInvalidAccordingToTheSchema($filename): void $this->not(fn () => $this->theJsonShouldBeValidAccordingToTheSchema($filename), 'The schema was valid'); } - /** - * @Then the JSON should be equal to: - */ + #[Then('the JSON should be equal to:')] public function theJsonShouldBeEqualTo(PyStringNode $content): void { $actual = $this->getJson(); @@ -357,9 +330,7 @@ public function theJsonShouldBeEqualTo(PyStringNode $content): void ); } - /** - * @Then print last JSON response - */ + #[Then('print last JSON response')] public function printLastJsonResponse(): void { echo $this->getJson() @@ -368,9 +339,8 @@ public function printLastJsonResponse(): void /** * Checks, that response JSON matches with a swagger dump. - * - * @Then the JSON should be valid according to swagger :dumpPath dump schema :schemaName */ + #[Then('the JSON should be valid according to swagger :dumpPath dump schema :schemaName')] public function theJsonShouldBeValidAccordingToTheSwaggerSchema($dumpPath, $schemaName): void { $this->checkSchemaFile($dumpPath); @@ -390,9 +360,8 @@ public function theJsonShouldBeValidAccordingToTheSwaggerSchema($dumpPath, $sche /** * Checks, that response JSON not matches with a swagger dump. - * - * @Then the JSON should not be valid according to swagger :dumpPath dump schema :schemaName */ + #[Then('the JSON should not be valid according to swagger :dumpPath dump schema :schemaName')] public function theJsonShouldNotBeValidAccordingToTheSwaggerSchema($dumpPath, $schemaName): void { $this->not(fn () => $this->theJsonShouldBeValidAccordingToTheSwaggerSchema($dumpPath, $schemaName), 'JSON Schema matches but it should not'); diff --git a/src/Context/RestContext.php b/src/Context/RestContext.php index 97a201d7..c473bad9 100644 --- a/src/Context/RestContext.php +++ b/src/Context/RestContext.php @@ -5,6 +5,8 @@ use Behat\Gherkin\Node\PyStringNode; use Behat\Gherkin\Node\TableNode; use Behat\Mink\Exception\ExpectationException; +use Behat\Step\Given; +use Behat\Step\Then; use Behatch\HttpCall\Request; class RestContext extends BaseContext @@ -21,9 +23,8 @@ public function __construct(Request $request) /** * Sends a HTTP request. - * - * @Given (I )send a :method request to :url */ + #[Given('(I )send a :method request to :url')] public function iSendARequestTo($method, $url, ?PyStringNode $body = null, $files = []) { return $this->request->send( @@ -37,9 +38,8 @@ public function iSendARequestTo($method, $url, ?PyStringNode $body = null, $file /** * Sends a HTTP request with a some parameters. - * - * @Given (I )send a :method request to :url with parameters: */ + #[Given('(I )send a :method request to :url with parameters:')] public function iSendARequestToWithParameters($method, $url, TableNode $data) { $files = []; @@ -67,9 +67,8 @@ public function iSendARequestToWithParameters($method, $url, TableNode $data) /** * Sends a HTTP request with a body. - * - * @Given (I )send a :method request to :url with body: */ + #[Given('(I )send a :method request to :url with body:')] public function iSendARequestToWithBody($method, $url, PyStringNode $body) { return $this->iSendARequestTo($method, $url, $body); @@ -77,10 +76,9 @@ public function iSendARequestToWithBody($method, $url, PyStringNode $body) /** * Checks, whether the response content is equal to given text. - * - * @Then the response should be equal to - * @Then the response should be equal to: */ + #[Then('the response should be equal to')] + #[Then('the response should be equal to:')] public function theResponseShouldBeEqualTo(PyStringNode $expected): void { $expected = str_replace('\\"', '"', (string) $expected); @@ -91,9 +89,8 @@ public function theResponseShouldBeEqualTo(PyStringNode $expected): void /** * Checks, whether the response content is null or empty string. - * - * @Then the response should be empty */ + #[Then('the response should be empty')] public function theResponseShouldBeEmpty(): void { $actual = $this->request->getContent(); @@ -103,9 +100,8 @@ public function theResponseShouldBeEmpty(): void /** * Checks, whether the header name is equal to given text. - * - * @Then the header :name should be equal to :value */ + #[Then('the header :name should be equal to :value')] public function theHeaderShouldBeEqualTo($name, $value): void { $actual = $this->request->getHttpHeader($name); @@ -116,9 +112,8 @@ public function theHeaderShouldBeEqualTo($name, $value): void /** * Checks, whether the header name is not equal to given text. - * - * @Then the header :name should not be equal to :value */ + #[Then('the header :name should not be equal to :value')] public function theHeaderShouldNotBeEqualTo($name, $value): void { $actual = $this->getSession()->getResponseHeader($name); @@ -138,9 +133,8 @@ public function theHeaderShouldBeContains($name, $value): void /** * Checks, whether the header name contains the given text. - * - * @Then the header :name should contain :value */ + #[Then('the header :name should contain :value')] public function theHeaderShouldContain($name, $value): void { $actual = $this->request->getHttpHeader($name); @@ -151,9 +145,8 @@ public function theHeaderShouldContain($name, $value): void /** * Checks, whether the header name doesn't contain the given text. - * - * @Then the header :name should not contain :value */ + #[Then('the header :name should not contain :value')] public function theHeaderShouldNotContain($name, $value): void { $this->assertNotContains($value, $this->request->getHttpHeader($name), @@ -163,9 +156,8 @@ public function theHeaderShouldNotContain($name, $value): void /** * Checks, whether the header not exist. - * - * @Then the header :name should not exist */ + #[Then('the header :name should not exist')] public function theHeaderShouldNotExist($name): void { $this->not(function () use ($name): void { @@ -178,9 +170,7 @@ protected function theHeaderShouldExist($name) return $this->request->getHttpHeader($name); } - /** - * @Then the header :name should match :regex - */ + #[Then('the header :name should match :regex')] public function theHeaderShouldMatch($name, $regex): void { $actual = $this->request->getHttpHeader($name); @@ -192,9 +182,7 @@ public function theHeaderShouldMatch($name, $regex): void ); } - /** - * @Then the header :name should not match :regex - */ + #[Then('the header :name should not match :regex')] public function theHeaderShouldNotMatch($name, $regex): void { $this->not( @@ -207,9 +195,8 @@ function () use ($name, $regex): void { /** * Checks, that the response header expire is in the future. - * - * @Then the response should expire in the future */ + #[Then('the response should expire in the future')] public function theResponseShouldExpireInTheFuture(): void { $date = new \DateTime($this->request->getHttpRawHeader('Date')[0]); @@ -222,17 +209,14 @@ public function theResponseShouldExpireInTheFuture(): void /** * Add an header element in a request. - * - * @Then (I )add :name header equal to :value */ + #[Then('(I )add :name header equal to :value')] public function iAddHeaderEqualTo($name, $value): void { $this->request->setHttpHeader($name, $value); } - /** - * @Then the response should be encoded in :encoding - */ + #[Then('the response should be encoded in :encoding')] public function theResponseShouldBeEncodedIn($encoding): void { $content = $this->request->getContent(); @@ -243,9 +227,7 @@ public function theResponseShouldBeEncodedIn($encoding): void $this->theHeaderShouldContain('Content-Type', "charset=$encoding"); } - /** - * @Then print last response headers - */ + #[Then('print last response headers')] public function printLastResponseHeaders(): void { $text = ''; @@ -257,9 +239,7 @@ public function printLastResponseHeaders(): void echo $text; } - /** - * @Then print the corresponding curl command - */ + #[Then('print the corresponding curl command')] public function printTheCorrespondingCurlCommand(): void { $method = $this->request->getMethod(); diff --git a/src/Context/SystemContext.php b/src/Context/SystemContext.php index 2066352b..0939ebb8 100644 --- a/src/Context/SystemContext.php +++ b/src/Context/SystemContext.php @@ -4,6 +4,9 @@ use Behat\Behat\Context\Context; use Behat\Gherkin\Node\PyStringNode; +use Behat\Hook\AfterScenario; +use Behat\Step\Given; +use Behat\Step\Then; class SystemContext implements Context { @@ -25,9 +28,8 @@ public static function getTranslationResources() /** * Execute a command. - * - * @Given (I )execute :command */ + #[Given('(I )execute :command')] public function iExecute($cmd): void { $start = microtime(true); @@ -39,9 +41,8 @@ public function iExecute($cmd): void /** * Execute a command from project root. - * - * @Given (I )execute :command from project root */ + #[Given('(I )execute :command from project root')] public function iExecuteFromProjectRoot($cmd): void { $cmd = $this->root.\DIRECTORY_SEPARATOR.$cmd; @@ -50,9 +51,8 @@ public function iExecuteFromProjectRoot($cmd): void /** * Display the last command output. - * - * @Then (I )display the last command output */ + #[Then('(I )display the last command output')] public function iDumpCommandOutput(): void { echo implode(\PHP_EOL, $this->output); @@ -60,9 +60,8 @@ public function iDumpCommandOutput(): void /** * Command should succeed. - * - * @Then command should succeed */ + #[Then('command should succeed')] public function commandShouldSucceed(): void { if (0 !== $this->lastReturnCode) { @@ -72,9 +71,8 @@ public function commandShouldSucceed(): void /** * Command should fail. - * - * @Then command should fail */ + #[Then('command should fail')] public function commandShouldFail(): void { if (0 === $this->lastReturnCode) { @@ -84,9 +82,8 @@ public function commandShouldFail(): void /** * Command should last less than. - * - * @Then command should last less than :seconds seconds */ + #[Then('command should last less than :seconds seconds')] public function commandShouldLastLessThan($seconds): void { if ($this->lastExecutionTime > $seconds) { @@ -96,9 +93,8 @@ public function commandShouldLastLessThan($seconds): void /** * Command should last more than. - * - * @Then command should last more than :seconds seconds */ + #[Then('command should last more than :seconds seconds')] public function commandShouldMoreLessThan($seconds): void { if ($this->lastExecutionTime < $seconds) { @@ -108,9 +104,8 @@ public function commandShouldMoreLessThan($seconds): void /** * Checks, that output contains specified text. - * - * @Then output should contain :text */ + #[Then('output should contain :text')] public function outputShouldContain($text): void { $regex = '~'.$text.'~ui'; @@ -130,9 +125,8 @@ public function outputShouldContain($text): void /** * Checks, that output not contains specified text. - * - * @Then output should not contain :text */ + #[Then('output should not contain :text')] public function outputShouldNotContain($text): void { $regex = '~'.$text.'~ui'; @@ -144,9 +138,7 @@ public function outputShouldNotContain($text): void } } - /** - * @Given output should be: - */ + #[Given('output should be:')] public function outputShouldBe(PyStringNode $string): void { $expected = $string->getStrings(); @@ -157,9 +149,7 @@ public function outputShouldBe(PyStringNode $string): void } } - /** - * @Given output should not be: - */ + #[Given('output should not be:')] public function outputShouldNotBe(PyStringNode $string): void { $expected = $string->getStrings(); @@ -177,10 +167,8 @@ public function outputShouldNotBe(PyStringNode $string): void } } - /** - * @Given (I )create the file :filename containing: - * @Given (I )create the file :filename contening: - */ + #[Given('(I )create the file :filename containing:')] + #[Given('(I )create the file :filename contening:')] public function iCreateTheFileContaining($filename, PyStringNode $string): void { if (!is_file($filename)) { @@ -191,9 +179,7 @@ public function iCreateTheFileContaining($filename, PyStringNode $string): void } } - /** - * @Then print the content of :filename file - */ + #[Then('print the content of :filename file')] public function printTheContentOfFile($filename): void { if (is_file($filename)) { @@ -203,9 +189,7 @@ public function printTheContentOfFile($filename): void } } - /** - * @AfterScenario - */ + #[AfterScenario] public function after(): void { foreach ($this->createdFiles as $filename) { diff --git a/src/Context/TableContext.php b/src/Context/TableContext.php index 619c11c3..5e58a6ec 100644 --- a/src/Context/TableContext.php +++ b/src/Context/TableContext.php @@ -3,14 +3,14 @@ namespace Behatch\Context; use Behat\Gherkin\Node\TableNode; +use Behat\Step\Then; class TableContext extends BaseContext { /** * Checks that the specified table's columns match the given schema. - * - * @Then the columns schema of the :table table should match: */ + #[Then('the columns schema of the :table table should match:')] public function theColumnsSchemaShouldMatch(string $table, TableNode $text): void { $columnsSelector = "$table thead tr th"; @@ -25,9 +25,8 @@ public function theColumnsSchemaShouldMatch(string $table, TableNode $text): voi /** * Checks that the specified table contains the given number of columns. - * - * @Then (I )should see :count column(s) in the :table table */ + #[Then('(I )should see :count column(s) in the :table table')] public function iShouldSeeColumnsInTheTable(int $count, string $table): void { $columnsSelector = "$table thead tr th"; @@ -38,9 +37,8 @@ public function iShouldSeeColumnsInTheTable(int $count, string $table): void /** * Checks that the specified table contains the specified number of rows in its body. - * - * @Then (I )should see :count rows in the :index :table table */ + #[Then('(I )should see :count rows in the :index :table table')] public function iShouldSeeRowsInTheNthTable(int $count, int $index, string $table): void { $actual = $this->countElements('tbody tr', $index, $table); @@ -49,9 +47,8 @@ public function iShouldSeeRowsInTheNthTable(int $count, int $index, string $tabl /** * Checks that the specified table contains the specified number of rows in its body. - * - * @Then (I )should see :count row(s) in the :table table */ + #[Then('(I )should see :count row(s) in the :table table')] public function iShouldSeeRowsInTheTable(int $count, string $table): void { $this->iShouldSeeRowsInTheNthTable($count, 1, $table); @@ -59,9 +56,8 @@ public function iShouldSeeRowsInTheTable(int $count, string $table): void /** * Checks that the data of the specified row matches the given schema. - * - * @Then the data in the :index row of the :table table should match: */ + #[Then('the data in the :index row of the :table table should match:')] public function theDataOfTheRowShouldMatch(int $index, string $table, TableNode $text): void { $rowsSelector = "$table tbody tr"; @@ -87,9 +83,8 @@ public function theDataOfTheRowShouldMatch(int $index, string $table, TableNode /** * Checks that the specified cell (column/row) of the table's body contains the specified text. - * - * @Then the :colIndex column of the :rowIndex row in the :table table should contain :text */ + #[Then('the :colIndex column of the :rowIndex row in the :table table should contain :text')] public function theStColumnOfTheStRowInTheTableShouldContain(int $colIndex, int $rowIndex, string $table, string $text): void { $rowSelector = "$table tbody tr"; diff --git a/src/Context/XmlContext.php b/src/Context/XmlContext.php index 1fa4ae8d..8e42c672 100644 --- a/src/Context/XmlContext.php +++ b/src/Context/XmlContext.php @@ -3,15 +3,16 @@ namespace Behatch\Context; use Behat\Gherkin\Node\PyStringNode; +use Behat\Hook\BeforeScenario; +use Behat\Step\Then; use Behatch\Xml\Dom; class XmlContext extends BaseContext { /** * Checks that the response is correct XML. - * - * @Then the response should be in XML */ + #[Then('the response should be in XML')] public function theResponseShouldBeInXml(): void { $this->getDom(); @@ -19,9 +20,8 @@ public function theResponseShouldBeInXml(): void /** * Checks that the response is not correct XML. - * - * @Then the response should not be in XML */ + #[Then('the response should not be in XML')] public function theResponseShouldNotBeInXml(): void { $this->not( @@ -38,9 +38,8 @@ public function theResponseShouldNotBeInXml(): void * @throws \Exception * * @return \DomNodeList - * - * @Then the XML element :element should exist(s) */ + #[Then('the XML element :element should exist(s)')] public function theXmlElementShouldExist($element) { $elements = $this->getDom() @@ -55,9 +54,8 @@ public function theXmlElementShouldExist($element) /** * Checks that the specified XML element does not exist. - * - * @Then the XML element :element should not exist(s) */ + #[Then('the XML element :element should not exist(s)')] public function theXmlElementShouldNotExist($element): void { $this->not(function () use ($element): void { @@ -67,9 +65,8 @@ public function theXmlElementShouldNotExist($element): void /** * Checks that the specified XML element is equal to the given value. - * - * @Then the XML element :element should be equal to :text */ + #[Then('the XML element :element should be equal to :text')] public function theXmlElementShouldBeEqualTo($element, $text): void { $elements = $this->theXmlElementShouldExist($element); @@ -83,9 +80,8 @@ public function theXmlElementShouldBeEqualTo($element, $text): void /** * Checks that the specified XML element is not equal to the given value. - * - * @Then the XML element :element should not be equal to :text */ + #[Then('the XML element :element should not be equal to :text')] public function theXmlElementShouldNotBeEqualTo($element, $text): void { $this->not(fn () => $this->theXmlElementShouldBeEqualTo($element, $text), "The element '$element' value is not '$text'"); @@ -93,9 +89,8 @@ public function theXmlElementShouldNotBeEqualTo($element, $text): void /** * Checks that the XML attribute on the specified element exists. - * - * @Then the XML attribute :attribute on element :element should exist(s) */ + #[Then('the XML attribute :attribute on element :element should exist(s)')] public function theXmlAttributeShouldExist($attribute, $element) { $elements = $this->theXmlElementShouldExist("{$element}[@{$attribute}]"); @@ -115,9 +110,8 @@ public function theXmlAttributeShouldExist($attribute, $element) /** * Checks that the XML attribute on the specified element does not exist. - * - * @Then the XML attribute :attribute on element :element should not exist(s) */ + #[Then('the XML attribute :attribute on element :element should not exist(s)')] public function theXmlAttributeShouldNotExist($attribute, $element): void { $this->theXmlElementShouldNotExist("{$element}[@{$attribute}]"); @@ -125,9 +119,8 @@ public function theXmlAttributeShouldNotExist($attribute, $element): void /** * Checks that the XML attribute on the specified element is equal to the given value. - * - * @Then the XML attribute :attribute on element :element should be equal to :text */ + #[Then('the XML attribute :attribute on element :element should be equal to :text')] public function theXmlAttributeShouldBeEqualTo($attribute, $element, $text): void { $actual = $this->theXmlAttributeShouldExist($attribute, $element); @@ -139,9 +132,8 @@ public function theXmlAttributeShouldBeEqualTo($attribute, $element, $text): voi /** * Checks that the XML attribute on the specified element is not equal to the given value. - * - * @Then the XML attribute :attribute on element :element should not be equal to :text */ + #[Then('the XML attribute :attribute on element :element should not be equal to :text')] public function theXmlAttributeShouldNotBeEqualTo($attribute, $element, $text): void { $actual = $this->theXmlAttributeShouldExist($attribute, $element); @@ -153,9 +145,8 @@ public function theXmlAttributeShouldNotBeEqualTo($attribute, $element, $text): /** * Checks that the given XML element has N child element(s). - * - * @Then the XML element :element should have :count element(s) */ + #[Then('the XML element :element should have :count element(s)')] public function theXmlElementShouldHaveNChildElements($element, $count): void { $elements = $this->theXmlElementShouldExist($element); @@ -172,9 +163,8 @@ public function theXmlElementShouldHaveNChildElements($element, $count): void /** * Checks that the given XML element contains the given value. - * - * @Then the XML element :element should contain :text */ + #[Then('the XML element :element should contain :text')] public function theXmlElementShouldContain($element, $text): void { $elements = $this->theXmlElementShouldExist($element); @@ -184,9 +174,8 @@ public function theXmlElementShouldContain($element, $text): void /** * Checks that the given XML element does not contain the given value. - * - * @Then the XML element :element should not contain :text */ + #[Then('the XML element :element should not contain :text')] public function theXmlElementShouldNotContain($element, $text): void { $elements = $this->theXmlElementShouldExist($element); @@ -196,9 +185,8 @@ public function theXmlElementShouldNotContain($element, $text): void /** * Checks that the XML uses the specified namespace. - * - * @Then the XML should use the namespace :namespace */ + #[Then('the XML should use the namespace :namespace')] public function theXmlShouldUseTheNamespace($namespace): void { $namespaces = $this->getDom() @@ -211,9 +199,8 @@ public function theXmlShouldUseTheNamespace($namespace): void /** * Checks that the XML does not use the specified namespace. - * - * @Then the XML should not use the namespace :namespace */ + #[Then('the XML should not use the namespace :namespace')] public function theXmlShouldNotUseTheNamespace($namespace): void { $namespaces = $this->getDom() @@ -226,26 +213,21 @@ public function theXmlShouldNotUseTheNamespace($namespace): void /** * Optimistically (ignoring errors) attempt to pretty-print the last XML response. - * - * @Then print last XML response */ + #[Then('print last XML response')] public function printLastXmlResponse(): void { echo (string) $this->getDom(); } - /** - * @BeforeScenario - */ + #[BeforeScenario] public function beforeScenario(): void { libxml_clear_errors(); libxml_use_internal_errors(true); } - /** - * @Then the XML feed should be valid according to its DTD - */ + #[Then('the XML feed should be valid according to its DTD')] public function theXmlFeedShouldBeValidAccordingToItsDtd(): void { try { @@ -255,9 +237,7 @@ public function theXmlFeedShouldBeValidAccordingToItsDtd(): void } } - /** - * @Then the XML feed should be valid according to the XSD :filename - */ + #[Then('the XML feed should be valid according to the XSD :filename')] public function theXmlFeedShouldBeValidAccordingToTheXsd($filename): void { if (is_file($filename)) { @@ -269,18 +249,14 @@ public function theXmlFeedShouldBeValidAccordingToTheXsd($filename): void } } - /** - * @Then the XML feed should be valid according to this XSD: - */ + #[Then('the XML feed should be valid according to this XSD:')] public function theXmlFeedShouldBeValidAccordingToThisXsd(PyStringNode $xsd): void { $this->getDom() ->validateXsd($xsd->getRaw()); } - /** - * @Then the XML feed should be valid according to the relax NG schema :filename - */ + #[Then('the XML feed should be valid according to the relax NG schema :filename')] public function theXmlFeedShouldBeValidAccordingToTheRelaxNgSchema($filename): void { if (is_file($filename)) { @@ -292,18 +268,14 @@ public function theXmlFeedShouldBeValidAccordingToTheRelaxNgSchema($filename): v } } - /** - * @Then the XML feed should be valid according to this relax NG schema: - */ + #[Then('the XML feed should be valid according to this relax NG schema:')] public function theXmlFeedShouldBeValidAccordingToThisRelaxNgSchema(PyStringNode $ng): void { $this->getDom() ->validateNg($ng->getRaw()); } - /** - * @Then the atom feed should be valid - */ + #[Then('the atom feed should be valid')] public function theAtomFeedShouldBeValid(): void { $this->theXmlFeedShouldBeValidAccordingToTheXsd( @@ -311,9 +283,7 @@ public function theAtomFeedShouldBeValid(): void ); } - /** - * @Then the RSS2 feed should be valid - */ + #[Then('the RSS2 feed should be valid')] public function theRss2FeedShouldBeValid(): void { $this->theXmlFeedShouldBeValidAccordingToTheXsd( diff --git a/src/Extension.php b/src/Extension.php index 3b619597..e926ce22 100644 --- a/src/Extension.php +++ b/src/Extension.php @@ -13,7 +13,7 @@ class Extension implements ExtensionInterface { - public function getConfigKey() + public function getConfigKey(): string { return 'behatch'; } diff --git a/src/Html.php b/src/Html.php index 2adc797e..29fc154e 100644 --- a/src/Html.php +++ b/src/Html.php @@ -2,9 +2,11 @@ namespace Behatch; +use Behat\Mink\Session; + trait Html { - abstract protected function getSession($name = null); + abstract public function getSession(?string $name = null): Session; protected function countElements($element, $index, $parent) { diff --git a/src/HttpCall/HttpCallListener.php b/src/HttpCall/HttpCallListener.php index 577914ef..dee30e85 100644 --- a/src/HttpCall/HttpCallListener.php +++ b/src/HttpCall/HttpCallListener.php @@ -23,7 +23,7 @@ public function __construct(ContextSupportedVoter $contextSupportedVoter, HttpCa $this->mink = $mink; } - public static function getSubscribedEvents() + public static function getSubscribedEvents(): array { return [ StepTested::AFTER => 'afterStep', diff --git a/src/HttpCall/HttpCallResultPoolResolver.php b/src/HttpCall/HttpCallResultPoolResolver.php index e34f7da5..f3f679b3 100644 --- a/src/HttpCall/HttpCallResultPoolResolver.php +++ b/src/HttpCall/HttpCallResultPoolResolver.php @@ -17,7 +17,7 @@ public function __construct(/* ... */) } } - public function resolveArguments(\ReflectionClass $classReflection, array $arguments) + public function resolveArguments(\ReflectionClass $classReflection, array $arguments): array { if (null !== ($constructor = $classReflection->getConstructor())) { foreach ($constructor->getParameters() as $parameter) {