Skip to content

Commit

Permalink
Allow selenium image configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
NoelDeMartin committed Feb 6, 2024
1 parent 8124fe7 commit 15ee698
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 31 deletions.
3 changes: 3 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ The format of this change log follows the advice given at [Keep a CHANGELOG](htt

## [Unreleased]

### Added
- `--selenium` option to `behat` to specify Selenium Docker image.

### Changed
- Updated all uses of `actions/checkout` from `v3` (using node 16) to `v4` (using node 20), because [actions using node 16 are deprecated](https://github.blog/changelog/2023-09-22-github-actions-transitioning-from-node-16-to-node-20/) and will stop working in the future.
* ACTION SUGGESTED: In order to avoid the node 16 deprecation warnings, update your workflows to use `actions/checkout@v4`.
Expand Down
14 changes: 12 additions & 2 deletions docs/CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ Run Behat on a plugin

### Usage

* `behat [-m|--moodle MOODLE] [-p|--profile PROFILE] [--suite SUITE] [--tags TAGS] [--name NAME] [--start-servers] [--auto-rerun AUTO-RERUN] [--dump] [--] <plugin>`
* `behat [-m|--moodle MOODLE] [-p|--profile PROFILE] [--suite SUITE] [--tags TAGS] [--name NAME] [--start-servers] [--auto-rerun AUTO-RERUN] [--selenium SELENIUM] [--dump] [--] <plugin>`

Run Behat on a plugin

Expand Down Expand Up @@ -327,6 +327,16 @@ Number of times to rerun failures
* Is negatable: no
* Default: `2`

#### `--selenium`

Selenium Docker image

* Accept value: yes
* Is value required: no
* Is multiple: no
* Is negatable: no
* Default: `NULL`

#### `--dump`

Print contents of Behat failure HTML files
Expand Down Expand Up @@ -2385,4 +2395,4 @@ Do not ask any interactive question
* Is value required: no
* Is multiple: no
* Is negatable: no
* Default: `false`
* Default: `false`
47 changes: 21 additions & 26 deletions src/Command/BehatCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,6 @@ class BehatCommand extends AbstractMoodleCommand
{
use ExecuteTrait;

/**
* Selenium legacy Firefox image.
*/
private string $seleniumLegacyFirefoxImage = 'selenium/standalone-firefox:2.53.1';

/**
* Selenium standalone Firefox image.
*
* @todo: Make this configurable.
*/
private string $seleniumFirefoxImage = 'selenium/standalone-firefox:3';

/**
* Selenium standalone Chrome image.
*
* @todo: Make this configurable.
*/
private string $seleniumChromeImage = 'selenium/standalone-chrome:3';

/**
* Wait this many microseconds for Selenium server to start/stop.
*
Expand All @@ -65,6 +46,7 @@ protected function configure(): void
->addOption('name', null, InputOption::VALUE_REQUIRED, 'Behat name option to use', '')
->addOption('start-servers', null, InputOption::VALUE_NONE, 'Start Selenium and PHP servers')
->addOption('auto-rerun', null, InputOption::VALUE_REQUIRED, 'Number of times to rerun failures', 2)
->addOption('selenium', null, InputOption::VALUE_NONE, 'Selenium Docker image')
->addOption('dump', null, InputOption::VALUE_NONE, 'Print contents of Behat failure HTML files')
->setDescription('Run Behat on a plugin');
}
Expand Down Expand Up @@ -150,13 +132,7 @@ private function startServerProcesses(InputInterface $input): void
$profile = getenv('MOODLE_BEHAT_DEFAULT_BROWSER') ?: (getenv('MOODLE_APP') ? 'chrome' : 'firefox');
}

if ($profile === 'chrome') {
$image = $this->seleniumChromeImage;
} elseif ($this->usesLegacyPhpWebdriver()) {
$image = $this->seleniumLegacyFirefoxImage;
} else {
$image = $this->seleniumFirefoxImage;
}
$image = $this->getSeleniumImage($input, $profile);

$cmd = [
'docker',
Expand Down Expand Up @@ -226,4 +202,23 @@ private function usesLegacyPhpWebdriver(): bool

return strpos(file_get_contents($composerlock), 'instaclick/php-webdriver') !== false;
}

private function getSeleniumImage(InputInterface $input, string $profile): string
{
$image = $input->getOption('selenium') ?: getenv('MOODLE_BEHAT_SELENIUM_IMAGE');

if (!empty($image)) {
return $image;
}

if ($profile === 'chrome') {
return getenv('MOODLE_BEHAT_SELENIUM_CHROME_IMAGE') ?: 'selenium/standalone-chrome:3';
}

if ($this->usesLegacyPhpWebdriver()) {
return 'selenium/standalone-firefox:2.53.1';

Check warning on line 219 in src/Command/BehatCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Command/BehatCommand.php#L219

Added line #L219 was not covered by tests
}

return getenv('MOODLE_BEHAT_SELENIUM_FIREFOX_IMAGE') ?: 'selenium/standalone-firefox:3';
}
}
42 changes: 41 additions & 1 deletion tests/Command/BehatCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ protected function executeCommand($pluginDir = null, $moodleDir = null, array $c
$cmdOptions
);
$commandTester->execute($cmdOptions);
$this->lastCmd = $command->execute->lastCmd; // We need this for assertions against the command run.

// We need these for assertions against the commands run.
$this->allCmds = $command->execute->allCmds;
$this->lastCmd = $command->execute->lastCmd;

return $commandTester;
}
Expand All @@ -69,6 +72,43 @@ public function testExecuteWithTags()
$this->assertDoesNotMatchRegularExpression('/--tags=@local_ci/', $this->lastCmd);
}

public function testExecuteWithSeleniumImageOption()
{
$commandTester = $this->executeCommand(null, null, ['--start-servers' => true, '--selenium' => 'seleniarm/standalone-chromium:latest']);
$this->assertSame(0, $commandTester->getStatusCode());
$this->assertMatchesRegularExpression('/seleniarm\/standalone-chromium:latest/', $this->allCmds[1]);
}

public function testExecuteWithSeleniumImageEnv()
{
putenv('MOODLE_BEHAT_SELENIUM_IMAGE=seleniarm/standalone-chromium:latest');

$commandTester = $this->executeCommand(null, null, ['--start-servers' => true]);
$this->assertSame(0, $commandTester->getStatusCode());
$this->assertMatchesRegularExpression('/seleniarm\/standalone-chromium:latest/', $this->allCmds[1]);
}

public function testExecuteWithSeleniumImageChromeEnv()
{
putenv('MOODLE_BEHAT_SELENIUM_IMAGE=');
putenv('MOODLE_BEHAT_SELENIUM_CHROME_IMAGE=selenium/standalone-chrome:4');

$commandTester = $this->executeCommand(null, null, ['--start-servers' => true, '--profile' => 'chrome']);
$this->assertSame(0, $commandTester->getStatusCode());
$this->assertMatchesRegularExpression('/selenium\/standalone-chrome:4/', $this->allCmds[1]);
}

public function testExecuteWithSeleniumImageFirefoxEnv()
{
putenv('MOODLE_BEHAT_SELENIUM_IMAGE=');
putenv('MOODLE_BEHAT_SELENIUM_FIREFOX_IMAGE=selenium/standalone-firefox:4');
file_put_contents("{$this->moodleDir}/composer.lock", '');

$commandTester = $this->executeCommand(null, null, ['--start-servers' => true, '--profile' => 'firefox']);
$this->assertSame(0, $commandTester->getStatusCode());
$this->assertMatchesRegularExpression('/selenium\/standalone-firefox:4/', $this->allCmds[1]);
}

public function testExecuteWithName()
{
$featureName = 'With "double quotes" and \'single quotes\'';
Expand Down
5 changes: 4 additions & 1 deletion tests/Command/PHPUnitCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ protected function executeCommand($pluginDir = null, $moodleDir = null, array $c
$cmdOptions
);
$commandTester->execute($cmdOptions);
$this->lastCmd = $command->execute->lastCmd; // We need this for assertions against the command run.

// We need these for assertions against the commands run.
$this->allCmds = $command->execute->allCmds;
$this->lastCmd = $command->execute->lastCmd;

return $commandTester;
}
Expand Down
6 changes: 5 additions & 1 deletion tests/MoodleTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@ class MoodleTestCase extends FilesystemTestCase
{
protected string $moodleDir;
protected string $pluginDir;
protected string $lastCmd = ''; // We need this for assertions against the command run.

// We need these for assertions against the commands run.
protected array $allCmds = [];
protected string $lastCmd = '';

protected function setUp(): void
{
parent::setUp();

$this->moodleDir = $this->tempDir;
$this->pluginDir = $this->tempDir . '/local/ci';
$this->allCmds = [];
$this->lastCmd = '';

$this->fs->mirror(__DIR__ . '/Fixture/moodle', $this->moodleDir);
Expand Down

0 comments on commit 15ee698

Please sign in to comment.