Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -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
27 changes: 26 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
}
14 changes: 14 additions & 0 deletions phpcs.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0"?>
<ruleset name="frontkom_as">
<arg name="encoding" value="utf-8"/>
<file>./src</file>
<file>./tests</file>
<rule ref="./vendor/squizlabs/php_codesniffer/src/Standards/PSR2"/>
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace" />
<rule ref="SlevomatCodingStandard.Arrays.TrailingArrayComma"/>
<rule ref="SlevomatCodingStandard.Namespaces.UnusedUses"/>
<rule ref="SlevomatCodingStandard.PHP.ShortList"/>
<rule ref="Generic.Arrays.DisallowLongArraySyntax.Found">
<type>warning</type>
</rule>
</ruleset>
5 changes: 5 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
parameters:
level: 5
paths:
- src
- tests
23 changes: 23 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
bootstrap="vendor/autoload.php"
cacheDirectory=".phpunit.cache"
executionOrder="depends,defects"
beStrictAboutOutputDuringTests="true"
displayDetailsOnPhpunitDeprecations="true"
failOnPhpunitDeprecation="true"
failOnRisky="true"
failOnWarning="true">
<testsuites>
<testsuite name="default">
<directory>tests</directory>
</testsuite>
</testsuites>

<source restrictDeprecations="true" restrictNotices="true" restrictWarnings="true">
<include>
<directory>src</directory>
</include>
</source>
</phpunit>
36 changes: 29 additions & 7 deletions src/CommonFeatureContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -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++;
Expand Down Expand Up @@ -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 = <<<JS
public function scrollSelectorIntoView($selector)
{
$function = <<<JS
(function(){
var elem = jQuery("$selector")[0];
elem.scrollIntoView(false);
Expand All @@ -77,8 +100,7 @@ public function scrollSelectorIntoView($selector) {
JS;
try {
$this->getSession()->executeScript($function);
}
catch (\Exception $e) {
} catch (\Exception $e) {
throw new \Exception("ScrollIntoView failed: " . $e->getMessage());
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/ElementExistsTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
44 changes: 26 additions & 18 deletions src/GutenbergContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}
}
}
}

}
98 changes: 49 additions & 49 deletions src/JsErrorsDumper.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Empty file added tests/.gitkeep
Empty file.