diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000..db3c7ec
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,43 @@
+name: Test
+on:
+ - push
+ - pull_request
+
+jobs:
+ test:
+ name: Run tests
+ runs-on: 'ubuntu-latest'
+ strategy:
+ fail-fast: false
+ matrix:
+ php-version:
+ - "7.4"
+ - "8.0"
+ - "8.1"
+ - "8.2"
+ - "8.3"
+ - "8.4"
+ steps:
+
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php-version }}
+
+ - name: Update composer
+ run: composer --verbose self-update --2
+
+ - name: Dump composer version
+ run: composer --version
+
+ - name: Validate composer.json
+ run: composer --verbose validate
+
+ - name: Install dependencies
+ run: composer --verbose install
+
+ - name: Run tests
+ run: composer test
diff --git a/composer.json b/composer.json
index 2a2323a..f5a4d41 100644
--- a/composer.json
+++ b/composer.json
@@ -6,5 +6,30 @@
"psr-4": {
"Frontkom\\CommonBehatDefinitions\\": "src/"
}
- }
+ },
+ "scripts": {
+ "test": [
+ "@composer phpcs",
+ "phpstan",
+ "phpunit"
+ ],
+ "phpcs": "vendor/bin/phpcs -p"
+ },
+ "require": {
+ "behat/behat": "^3.0",
+ "behat/mink": "^1.0",
+ "behat/mink-selenium2-driver": "^1.0",
+ "friends-of-behat/mink-extension": "^2.0"
+ },
+ "require-dev": {
+ "squizlabs/php_codesniffer": "^3.10",
+ "slevomat/coding-standard": "^8.15",
+ "phpunit/phpunit": "^9.0 || ^10.5",
+ "phpstan/phpstan": "^1.12"
+ },
+ "config": {
+ "allow-plugins": {
+ "dealerdirect/phpcodesniffer-composer-installer": true
+ }
+ }
}
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
new file mode 100644
index 0000000..00e518a
--- /dev/null
+++ b/phpcs.xml.dist
@@ -0,0 +1,14 @@
+
+
+
+ ./src
+ ./tests
+
+
+
+
+
+
+ warning
+
+
diff --git a/phpstan.neon b/phpstan.neon
new file mode 100644
index 0000000..46b0f47
--- /dev/null
+++ b/phpstan.neon
@@ -0,0 +1,5 @@
+parameters:
+ level: 5
+ paths:
+ - src
+ - tests
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
new file mode 100644
index 0000000..fa0a74d
--- /dev/null
+++ b/phpunit.xml.dist
@@ -0,0 +1,23 @@
+
+
+
+
+ tests
+
+
+
+
+
+ src
+
+
+
diff --git a/src/CommonFeatureContext.php b/src/CommonFeatureContext.php
index f48e015..38e3dc1 100644
--- a/src/CommonFeatureContext.php
+++ b/src/CommonFeatureContext.php
@@ -24,14 +24,18 @@ public function iWaitUntilElementIsVisible($selector)
{
$elements = $this->getSession()->getPage()->findAll('css', $selector);
if (count($elements) !== 1) {
- throw new \Exception('Expected to find exactly one element by selector ' . $selector . ' but found ' . count($elements) . ' elements');
+ throw new \Exception(
+ 'Expected to find exactly one element by selector ' .
+ $selector .
+ ' but found ' . count($elements) . ' elements'
+ );
}
/** @var \Behat\Mink\Element\NodeElement $element */
$element = reset($elements);
$i = 0;
- while (TRUE) {
+ while (true) {
if ($element->isVisible()) {
- return;
+ return;
}
sleep(1);
$i++;
@@ -61,14 +65,33 @@ public function iWaitSeconds($count)
usleep($count * 1000000);
}
+ /**
+ * Set the viewport to something defined as desktop.
+ *
+ * If you need to override this, simply create a class that extends this
+ * class, and reference that class inside your behat.yml file.
+ *
+ * @Given viewport is desktop
+ * @Given the viewport is desktop
+ */
+ public function iSetDesktopViewport()
+ {
+ $mink = $this->getMink();
+ if (!$mink->getSession()->isStarted()) {
+ $mink->getSession()->start();
+ }
+ $this->getSession()->resizeWindow(self::WIDTH, self::HEIGHT, 'current');
+ }
+
/**
* Scroll something into view.
*
* @Then I scroll element :selector into view
* @Then I scroll :selector into view
*/
- public function scrollSelectorIntoView($selector) {
- $function = <<getSession()->executeScript($function);
- }
- catch (\Exception $e) {
+ } catch (\Exception $e) {
throw new \Exception("ScrollIntoView failed: " . $e->getMessage());
}
}
diff --git a/src/ElementExistsTrait.php b/src/ElementExistsTrait.php
index e711f1b..86aefcc 100644
--- a/src/ElementExistsTrait.php
+++ b/src/ElementExistsTrait.php
@@ -14,7 +14,7 @@ trait ElementExistsTrait
* @Given I wait until element :arg1 exists
* @Given I wait until element :arg1 exists max :arg2 seconds
*/
- public function iWaitUntilElementExists($element, $seconds = NULL)
+ public function iWaitUntilElementExists($element, $seconds = null)
{
$seconds = (isset($seconds) && !empty($seconds)) ? $seconds : 10;
$waited = 0;
diff --git a/src/GutenbergContext.php b/src/GutenbergContext.php
index aa47842..323d9b7 100644
--- a/src/GutenbergContext.php
+++ b/src/GutenbergContext.php
@@ -4,39 +4,47 @@
use Behat\MinkExtension\Context\RawMinkContext;
-class GutenbergContext extends RawMinkContext {
+class GutenbergContext extends RawMinkContext
+{
/**
* Prepend a paragraph block basically.
*
* @Then /^I write text "([^"]*)" as a paragraph in the gutenberg field on the page$/
*/
- public function iWriteInTheGutenbergFieldOnThePage($text) {
- $js = sprintf("(function(){
+ public function iWriteInTheGutenbergFieldOnThePage($text)
+ {
+ $js = sprintf("(function(){
var block = wp.blocks.createBlock('core/paragraph', {content: '%s'});
wp.data.dispatch('core/editor').insertBlock(block, null);
return block.clientId;
})()", $text);
- $this->getSession()->evaluateScript($js);
- }
+ $this->getSession()->evaluateScript($js);
+ }
/**
* Step to wait for the editor to be ready.
*
* @Then /^I wait until gutenberg is ready$/
*/
- public function iWaitUntilGutenbergIsReady($max_wait = 10) {
- while (TRUE) {
- $is_ready = $this->getSession()->evaluateScript("wp && wp.data && wp.data.select && wp.data.select('core/editor').isCleanNewPost() || wp.data.select('core/block-editor').getBlockCount() > 0");
- if ($is_ready) {
- break;
- }
- sleep(1);
- $max_wait--;
- if ($max_wait <= 0) {
- throw new \Exception('Gutenberg did not load in time');
- }
+ public function iWaitUntilGutenbergIsReady($max_wait = 10)
+ {
+ while (true) {
+ $is_ready = $this->getSession()->evaluateScript(
+ "wp &&
+ wp.data &&
+ wp.data.select &&
+ wp.data.select('core/editor').isCleanNewPost() ||
+ wp.data.select('core/block-editor').getBlockCount() > 0"
+ );
+ if ($is_ready) {
+ break;
+ }
+ sleep(1);
+ $max_wait--;
+ if ($max_wait <= 0) {
+ throw new \Exception('Gutenberg did not load in time');
+ }
+ }
}
- }
-
}
diff --git a/src/JsErrorsDumper.php b/src/JsErrorsDumper.php
index e68917d..616ac42 100644
--- a/src/JsErrorsDumper.php
+++ b/src/JsErrorsDumper.php
@@ -9,65 +9,65 @@
/**
* Provides AfterStep that dumps any JS errors that appear during given step.
*/
-trait JsErrorsDumper {
+trait JsErrorsDumper
+{
/**
* Checks that the step did not trigger any JS errors.
*
* @AfterStep
*/
- public function lookForJsErrors(AfterStepScope $scope) {
- // No steps, nothing to do.
- if (!$scope->getStep()) {
- return;
- }
- $driver = $this->getSession()->getDriver();
- if (!($driver instanceof Selenium2Driver)) {
- // Only works in browsers.
- return;
- }
- // If the webdriver session has not started, probably means we are not
- // navigating in a context where we can actually evaluate any scripts at
- // all. This AfterStep will also trigger on steps in a background, for
- // example stuff like "Given a node with title something", which of course
- // will not let us have a browser window to check if there are any errors,
- // even if the driver of the session technically is a Selenium2Driver.
- try {
- if (!$driver->getWebDriverSession()) {
- return;
- }
- }
- catch (DriverException $e) {
- // This will happen at least in some version here if the session has not
- // been started yet.
- return;
- }
+ public function lookForJsErrors(AfterStepScope $scope)
+ {
+ // No steps, nothing to do.
+ if (!$scope->getStep()) {
+ return;
+ }
+ $driver = $this->getSession()->getDriver();
+ if (!($driver instanceof Selenium2Driver)) {
+ // Only works in browsers.
+ return;
+ }
+ // If the webdriver session has not started, probably means we are not
+ // navigating in a context where we can actually evaluate any scripts at
+ // all. This AfterStep will also trigger on steps in a background, for
+ // example stuff like "Given a node with title something", which of course
+ // will not let us have a browser window to check if there are any errors,
+ // even if the driver of the session technically is a Selenium2Driver.
+ try {
+ if (!$driver->getWebDriverSession()) {
+ return;
+ }
+ } catch (DriverException $e) {
+ // This will happen at least in some version here if the session has not
+ // been started yet.
+ return;
+ }
- try {
- $errors = $this->getSession()->evaluateScript("return window.jsErrors");
- } catch (\Exception $e) {
- // output where the error occurred for debugging purposes
- echo $this->scenarioData;
- throw $e;
- }
+ try {
+ $errors = $this->getSession()->evaluateScript("return window.jsErrors");
+ } catch (\Exception $e) {
+ // output where the error occurred for debugging purposes
+ echo $this->scenarioData;
+ throw $e;
+ }
- if (!$errors || empty($errors)) {
- return;
- }
-
- $file = sprintf("%s:%d", $scope->getFeature()->getFile(), $scope->getStep()->getLine());
- $message = sprintf("Found %d javascript error%s", count($errors), count($errors) > 0 ? 's' : '');
+ if (!$errors || empty($errors)) {
+ return;
+ }
- echo '-------------------------------------------------------------' . PHP_EOL;
- echo $file . PHP_EOL;
- echo $message . PHP_EOL;
- echo '-------------------------------------------------------------' . PHP_EOL;
+ $file = sprintf("%s:%d", $scope->getFeature()->getFile(), $scope->getStep()->getLine());
+ $message = sprintf("Found %d javascript error%s", count($errors), count($errors) > 0 ? 's' : '');
- foreach ($errors as $index => $error) {
- echo sprintf(" #%d: %s", $index, $error) . PHP_EOL;
- }
+ echo '-------------------------------------------------------------' . PHP_EOL;
+ echo $file . PHP_EOL;
+ echo $message . PHP_EOL;
+ echo '-------------------------------------------------------------' . PHP_EOL;
- throw new \Exception($message);
- }
+ foreach ($errors as $index => $error) {
+ echo sprintf(" #%d: %s", $index, $error) . PHP_EOL;
+ }
+ throw new \Exception($message);
+ }
}
diff --git a/tests/.gitkeep b/tests/.gitkeep
new file mode 100644
index 0000000..e69de29