Browse Source

Docker compose for testing (#9525)

* More ignore-patterns in eslint config

So we don't have to specify them on the command line when we check
codestyle locally.

* Test setup for local and CI using containers

It uses standalone containers for the greenmail IMAP server and the
standalone browser.
A testrunner image is built in the CI (for `linux/amd64` only, because
Github doesn't support multi-platform building on their default
runners and we don't have our own.)

This setup helps to run the tests (reproduceably) also locally.
Previously, on my machine, they produced varying results.
It also reduces the dependencies for running the browser test.
Local execution only depends on `docker compose`, no other tools
(previously it required `sudo`, `java`, and some more.)

The previous solution should still work, if you want it.

The scripts are stored in a directory called `.ci` to hide them a little
and avoid confusion with the container images from the
`roundcubemail-docker` repo.

* Fix UI tests by waiting for element before using it

This only was a flaky problem only occurring sometimes.

* Force a new IMAP connection in plugin tests, too

In other code the initial connection is forced. Doing this here, too,
fixes occasional problems with lost imap connections.

* Make waiting for zipfile's content more robust

* CI: Run tests from script on Windows, too

* CI: Do start local chrome if no connect URL is given

* Move compose.yml to tests/

This way it's less easy mistaken as usable for running Roundcubemail in
production.

* Move compose.yml to .ci/
pull/9552/head
Pablo Zmdl 1 year ago
committed by GitHub
parent
commit
85094706f9
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 58
      .ci/compose.yaml
  2. 16
      .ci/config-test.inc.php
  3. 48
      .ci/docker-images/Dockerfile
  4. 14
      .ci/docker-images/build.sh
  5. 59
      .ci/run_browser_tests.sh
  6. 19
      .ci/run_tests.sh
  7. 5
      .eslintrc.js
  8. 39
      .github/run.sh
  9. 58
      .github/workflows/browser_tests.yml
  10. 48
      .github/workflows/docker_image.yml
  11. 43
      .github/workflows/tests.yml
  12. 3
      plugins/archive/tests/Browser/MailTest.php
  13. 2
      plugins/markasjunk/tests/Browser/MailTest.php
  14. 37
      plugins/zipdownload/tests/Browser/MailTest.php
  15. 11
      tests/Browser/Browser.php
  16. 14
      tests/Browser/TestCase.php
  17. 0
      tests/Browser/downloads/.keep

58
.ci/compose.yaml

@ -0,0 +1,58 @@
services:
mailhost:
image: docker.io/greenmail/standalone
browserhost:
image: docker.io/selenium/standalone-chromium
volumes:
- '/dev/shm:/dev/shm'
- './Browser/downloads:/downloads'
browser_tests:
depends_on:
- mailhost
- browserhost
hostname: 'testrunner'
image: ghcr.io/roundcube/roundcubemail-testrunner:php8.3
volumes:
- '..:/app'
- './Browser/downloads:/downloads'
environment:
WEBDRIVER_CONNECT_URL: 'http://browserhost:4444'
SERVER_URL: 'http://testrunner:8000'
SERVER_BIND: '0.0.0.0:8000'
BROWSER_DOWNLOADS_DIR: '/downloads'
TESTRUNNER_DOWNLOADS_DIR: './Browser/downloads'
RC_CONFIG_IMAP_HOST: 'tls://mailhost:3143'
RC_CONFIG_SMTP_HOST: 'mailhost:3025'
command:
- .ci/run_browser_tests.sh
tests:
depends_on:
- mailhost
image: ghcr.io/roundcube/roundcubemail-testrunner:php8.3
volumes:
- '..:/app'
command:
- .ci/run_tests.sh
codespell:
image: ghcr.io/roundcube/roundcubemail-testrunner:php8.3
volumes:
- '..:/app'
command:
- vendor/bin/php-cs-fixer
- fix
- --dry-run
- --using-cache=no
- --diff
- --verbose
codestyle:
image: ghcr.io/roundcube/roundcubemail-testrunner:php8.3
volumes:
- '..:/app'
command:
- npx
- eslint
- .

16
.github/config-test.inc.php → .ci/config-test.inc.php

@ -6,11 +6,21 @@ $config = [];
$config['db_dsnw'] = 'sqlite:///' . sys_get_temp_dir() . '/roundcube-test-sqlite.db?mode=0646';
// Test user credentials
$config['tests_username'] = 'test';
$config['tests_password'] = 'test';
$config['tests_username'] = 'admin@example.net';
$config['tests_password'] = 'admin';
$config['imap_host'] = getenv('RC_CONFIG_IMAP_HOST') ?: 'localhost:143';
$config['imap_auth_type'] = 'IMAP';
$config['imap_conn_options'] = [
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
],
];
// $config['managesieve_host'] = 'localhost:4190';
// GreenMail
$config['smtp_host'] = 'localhost:25';
$config['smtp_host'] = getenv('RC_CONFIG_SMTP_HOST') ?: 'localhost:25';
// Settings required by the tests

48
.ci/docker-images/Dockerfile

@ -0,0 +1,48 @@
ARG PHPVERSION=8.3
FROM php:${PHPVERSION}-cli
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
libfreetype6-dev \
libicu-dev \
libjpeg62-turbo-dev \
libldap2-dev \
libpng-dev \
libpq-dev \
libsqlite3-dev \
libzip-dev \
libpspell-dev \
libonig-dev \
libldap-common \
libenchant-2-dev \
nodejs \
npm \
aspell \
aspell-en \
aspell-de \
hunspell-en-us \
git \
&& apt-get clean
# TODO: Do we need the multiarch-args? What for?
#RUN debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)" \
RUN docker-php-ext-configure gd --with-jpeg --with-freetype \
#&& docker-php-ext-configure ldap --with-libdir="lib/$debMultiarch" \
&& docker-php-ext-configure ldap \
&& docker-php-ext-install \
zip \
pcntl \
gd \
ldap \
intl \
pspell \
enchant
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
# Create working directory
WORKDIR /app
VOLUME /app

14
.ci/docker-images/build.sh

@ -0,0 +1,14 @@
#!/bin/bash
case "$1" in
8.1|8.3)
phpversion="$1"
;;
*)
echo "Error: first and only argument must be the wanted PHP version."
echo "Usage: $(basename $0) 8.1|8.3"
exit 1
;;
esac
exec docker build --build-arg "PHPVERSION=$phpversion" -f "$(realpath $(dirname $0)/Dockerfile)" -t "ghcr.io/pabzm/roundcubemail-testrunner:php$phpversion" "$(realpath $(dirname $0)/../../..)"

59
.ci/run_browser_tests.sh

@ -0,0 +1,59 @@
#!/bin/bash -ex
# The script is intended for use locally, as well as in the CI.
# It runs the browser-tests ("E2E" in the CI).
# It expects a running IMAP server (connection configured in
# `config-test.inc.php`, and a running Chrome/Chromium browser (connection
# hard-coded in code, overrideable via environment variables).
# Make temp and logs writeable to everyone.
chmod 777 temp logs
# Create downloads dir and ensure permissions (if it's set, the variable might
# be blank if tests are not run using containers).
if test -n "$TESTRUNNER_DOWNLOADS_DIR"; then
# Use sudo because in the Github action we apparently can't use a
# directory in $HOME or /tmp but another one for which we need
# superuser-rights.
install -m 777 -d "$TESTRUNNER_DOWNLOADS_DIR"
fi
if ! test -f config/config-test.inc.php; then
cp -v .ci/config-test.inc.php config/config-test.inc.php
fi
# Install dependencies for to remote control the browser.
composer require -n "nesbot/carbon:^2.62.1" --no-update
composer require -n "laravel/dusk:^7.9" --no-update
if $(echo $PHP_VERSION | grep -q '^8.3'); then
# Downgrade dependencies (for PHP 8.3 only)
composer update --prefer-dist --prefer-stable --prefer-lowest --no-interaction --no-progress --optimize-autoloader
else
composer update --prefer-dist --no-interaction --no-progress
fi
# Install development tools.
npm install
# Install javascript dependencies
bin/install-jsdeps.sh
# Compile Elastic's styles
npx lessc --clean-css="--s1 --advanced" skins/elastic/styles/styles.less > skins/elastic/styles/styles.min.css
npx lessc --clean-css="--s1 --advanced" skins/elastic/styles/print.less > skins/elastic/styles/print.min.css
npx lessc --clean-css="--s1 --advanced" skins/elastic/styles/embed.less > skins/elastic/styles/embed.min.css
# Use minified javascript files
bin/jsshrink.sh
# Run tests
echo "TESTS_MODE: DESKTOP"
TESTS_MODE=desktop vendor/bin/phpunit -c tests/Browser/phpunit.xml --fail-on-warning --fail-on-risky --exclude-group=failsonga
echo "TESTS_MODE: TABLET"
TESTS_MODE=tablet vendor/bin/phpunit -c tests/Browser/phpunit.xml --fail-on-warning --fail-on-risky --exclude-group=failsonga-tablet
# Mobile mode tests are unreliable on Github Actions
# echo "TESTS_MODE: PHONE"
# TESTS_MODE=phone vendor/bin/phpunit -c tests/Browser/phpunit.xml --fail-on-warning --fail-on-risky --exclude-group=failsonga-phone

19
.ci/run_tests.sh

@ -0,0 +1,19 @@
#!/bin/bash -ex
if ! test -f config/config-test.inc.php; then
cp -v .ci/config-test.inc.php config/config-test.inc.php
fi
composer require "kolab/net_ldap3:~1.1.4" --no-update
# Install dependencies, prefer highest.
composer update --prefer-dist --no-interaction --no-progress
# Execute tests.
vendor/bin/phpunit -c tests/phpunit.xml --fail-on-warning --fail-on-risky
# Downgrade dependencies to the lowest versions.
composer update --prefer-dist --prefer-stable --prefer-lowest --no-interaction --no-progress --optimize-autoloader
# Execute tests again.
vendor/bin/phpunit -c tests/phpunit.xml --fail-on-warning --fail-on-risky

5
.eslintrc.js

@ -16,6 +16,11 @@ module.exports = {
'/vendor',
'/public_html',
'/plugins/jqueryui/js',
'/plugins/managesieve/codemirror',
'/program/js/tinymce',
'/program/js/publickey.js',
'node_modules',
'*.min.js',
],
rules: {
'brace-style': ['error', '1tbs'],

39
.github/run.sh

@ -1,39 +0,0 @@
#!/bin/bash
# The script is intended for use on Travis with Trusty distribution
# It installs in-browser tests dependencies and prepares Roundcube instance
GMV=1.6.13
CHROMEVERSION=$(google-chrome-stable --version | tr -cd [:digit:].)
GMARGS="-Dgreenmail.setup.all -Dgreenmail.users=test:test -Dgreenmail.startup.timeout=3000"
# Make temp and logs writeable
sudo chmod 777 temp logs
# Install javascript dependencies
bin/install-jsdeps.sh
# Compile Elastic's styles
npx lessc --clean-css="--s1 --advanced" skins/elastic/styles/styles.less > skins/elastic/styles/styles.min.css
npx lessc --clean-css="--s1 --advanced" skins/elastic/styles/print.less > skins/elastic/styles/print.min.css
npx lessc --clean-css="--s1 --advanced" skins/elastic/styles/embed.less > skins/elastic/styles/embed.min.css
# Use minified javascript files
bin/jsshrink.sh
# Install proper WebDriver version for installed Chrome browser
php tests/Browser/install.php $CHROMEVERSION
# GreenMail server download, setup and start
wget -q https://repo1.maven.org/maven2/com/icegreen/greenmail-standalone/$GMV/greenmail-standalone-$GMV.jar \
&& (sudo java $GMARGS -jar greenmail-standalone-$GMV.jar &) \
&& sleep 10
# Run tests
echo "TESTS_MODE: DESKTOP" \
&& TESTS_MODE=desktop vendor/bin/phpunit -c tests/Browser/phpunit.xml --fail-on-warning --fail-on-risky --exclude-group=failsonga \
&& echo "TESTS_MODE: TABLET" \
&& TESTS_MODE=tablet vendor/bin/phpunit -c tests/Browser/phpunit.xml --fail-on-warning --fail-on-risky --exclude-group=failsonga-tablet \
# Mobile mode tests are unreliable on Github Actions
# && echo "TESTS_MODE: PHONE" \
# && TESTS_MODE=phone vendor/bin/phpunit -c tests/Browser/phpunit.xml --fail-on-warning --fail-on-risky --exclude-group=failsonga-phone \

58
.github/workflows/browser_tests.yml

@ -19,6 +19,30 @@ jobs:
name: Linux / PHP ${{ matrix.php }}
services:
mailhost:
image: docker.io/greenmail/standalone
ports:
- '3143:3143'
- '3025:3025'
browserhost:
image: docker.io/selenium/standalone-chromium
volumes:
- '/dev/shm:/dev/shm'
- ${{ github.workspace }}:/roundcubemail
ports:
- '4444:4444'
options: '--add-host=host.docker.internal:host-gateway'
env:
WEBDRIVER_CONNECT_URL: 'http://localhost:4444'
SERVER_URL: 'http://host.docker.internal:8000'
SERVER_BIND: '0.0.0.0:8000'
BROWSER_DOWNLOADS_DIR: '/roundcubemail/tests/Browser/downloads'
TESTRUNNER_DOWNLOADS_DIR: './tests/Browser/downloads'
RC_CONFIG_IMAP_HOST: 'tls://localhost:3143'
RC_CONFIG_SMTP_HOST: 'localhost:3025'
steps:
- name: Checkout code
uses: actions/checkout@v4
@ -31,12 +55,6 @@ jobs:
tools: composer:v2
coverage: none
- name: Set up JDK 1.8
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: '8'
- name: Setup NPM
uses: actions/setup-node@v4
with:
@ -48,22 +66,14 @@ jobs:
- name: Install Aspell
run: sudo apt-get -y install aspell aspell-en aspell-de
- name: Setup composer
run: |
composer require "nesbot/carbon:^2.62.1" --no-update
composer require "laravel/dusk:^7.9" --no-update
- name: Install dependencies
run: |
composer update --prefer-dist --no-interaction --no-progress
npm install
- name: Roundcube configuration
run: cp .github/config-test.inc.php config/config-test.inc.php
- name: Downgrade dependencies (for PHP 8.3 only)
if: matrix.php == '8.3'
run: composer update --prefer-dist --prefer-stable --prefer-lowest --no-interaction --no-progress --optimize-autoloader
- name: Execute tests
run: .github/run.sh
run: .ci/run_browser_tests.sh
- name: Upload screenshots as artifacts
# Upload screenshot if the test suite failed.
if: failure()
uses: actions/upload-artifact@v4
with:
name: screenshots
path: tests/Browser/screenshots

48
.github/workflows/docker_image.yml

@ -0,0 +1,48 @@
name: roundcubemail-testrunner image
on:
push:
paths:
- '.ci/docker-images/*'
- '.github/workflows/docker_image.yml'
jobs:
build_and_push:
strategy:
fail-fast: false
# Set up a matrix so we can add more versions to build with in the future.
matrix:
php: ["8.3"]
name: build and push with PHP ${{ matrix.php }}
runs-on: ubuntu-latest
# Set the permissions granted to the GITHUB_TOKEN for the actions in this job.
permissions:
contents: read
packages: write
attestations: write
id-token: write
steps:
- name: Check actor permission
uses: skjnldsv/check-actor-permission@v2
with:
require: admin
- name: Check out the repo
uses: actions/checkout@v4
- name: Log in to the Container registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Docker image
id: push
uses: docker/build-push-action@v2
with:
context: .
file: ./.ci/docker-images/Dockerfile
push: true
#platforms: linux/amd64,linux/arm64
build-args: PHPVERSION=${{ matrix.php }}
tags: "ghcr.io/roundcube/roundcubemail-testrunner:php${{ matrix.php }}"

43
.github/workflows/tests.yml

@ -37,17 +37,8 @@ jobs:
- name: Install Aspell/Hunspell
run: sudo apt-get -y install aspell aspell-en aspell-de hunspell-en-us
- name: Setup composer
run: composer require "kolab/net_ldap3:~1.1.4" --no-update
- name: Install dependencies
run: composer update --prefer-dist --no-interaction --no-progress
- name: Roundcube configuration
run: cp .github/config-test.inc.php config/config-test.inc.php
- name: Execute tests (highest)
run: vendor/bin/phpunit -c tests/phpunit.xml --fail-on-warning --fail-on-risky
- name: Execute tests
run: .ci/run_tests.sh
- name: Upload artifacts
uses: actions/upload-artifact@master
@ -56,12 +47,6 @@ jobs:
name: Logs
path: logs/errors.log
- name: Downgrade dependencies
run: composer update --prefer-dist --prefer-stable --prefer-lowest --no-interaction --no-progress --optimize-autoloader
- name: Execute tests (lowest)
run: vendor/bin/phpunit -c tests/phpunit.xml --fail-on-warning --fail-on-risky
tests_windows:
runs-on: windows-latest
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')"
@ -85,20 +70,12 @@ jobs:
tools: composer:v2
coverage: none
- name: Setup composer
run: composer require "kolab/net_ldap3:~1.1.4" --no-update
- name: Install dependencies
run: composer update --prefer-dist --no-interaction --no-progress
- name: Roundcube configuration
run: cp .github/config-test.inc.php config/config-test.inc.php
- name: Execute tests (highest)
run: vendor/bin/phpunit -c tests/phpunit.xml --fail-on-warning --fail-on-risky
- name: Execute tests
run: .ci/run_tests.sh
- name: Downgrade dependencies
run: composer update --prefer-dist --prefer-stable --prefer-lowest --no-interaction --no-progress --optimize-autoloader
- name: Execute tests (lowest)
run: vendor/bin/phpunit -c tests/phpunit.xml --fail-on-warning --fail-on-risky
- name: Upload artifacts
uses: actions/upload-artifact@master
if: failure()
with:
name: Logs
path: logs/errors.log

3
plugins/archive/tests/Browser/MailTest.php

@ -12,7 +12,7 @@ class MailTest extends TestCase
public static function setUpBeforeClass(): void
{
Bootstrap::init_db();
Bootstrap::init_imap();
Bootstrap::init_imap(true);
Bootstrap::purge_mailbox('INBOX');
Bootstrap::purge_mailbox('Archive');
@ -58,6 +58,7 @@ class MailTest extends TestCase
// Folders list
$browser->whenAvailable('#mailboxlist', static function ($browser) {
$browser->waitFor('li.mailbox.archive .unreadcount');
$browser->assertSeeIn('li.mailbox.archive .unreadcount', '1')
->click('li.mailbox.archive')
->waitUntilNotBusy();

2
plugins/markasjunk/tests/Browser/MailTest.php

@ -12,7 +12,7 @@ class MailTest extends TestCase
public static function setUpBeforeClass(): void
{
Bootstrap::init_db();
Bootstrap::init_imap();
Bootstrap::init_imap(true);
Bootstrap::purge_mailbox('INBOX');
Bootstrap::purge_mailbox('Junk');

37
plugins/zipdownload/tests/Browser/MailTest.php

@ -11,7 +11,7 @@ class MailTest extends TestCase
#[\Override]
public static function setUpBeforeClass(): void
{
Bootstrap::init_imap();
Bootstrap::init_imap(true);
Bootstrap::purge_mailbox('INBOX');
// import single email messages
@ -62,7 +62,7 @@ class MailTest extends TestCase
->click('a.download.mbox');
$filename = 'INBOX.zip';
$files = $this->getFilesFromZip($filename);
$files = $this->getFilesFromZip($browser, $filename);
$browser->removeDownloadedFile($filename);
$this->assertSame(['INBOX.mbox'], $files);
@ -70,14 +70,16 @@ class MailTest extends TestCase
// Test More > Download > Maildir format (two messages selected)
$browser->clickToolbarMenuItem('more', null, false)
->waitFor('#message-menu')
->with(new Popupmenu('message-menu'), static function ($browser) {
$browser->clickMenuItem('download', null, false);
})
->waitFor('#zipdownload-menu')
->with(new Popupmenu('zipdownload-menu'), function ($browser) {
$browser->click('a.download.maildir');
$filename = 'INBOX.zip';
$files = $this->getFilesFromZip($filename);
$files = $this->getFilesFromZip($browser, $filename);
$browser->removeDownloadedFile($filename);
$this->assertCount(2, $files);
});
@ -93,7 +95,7 @@ class MailTest extends TestCase
});
$filename = 'Lines.zip';
$files = $this->getFilesFromZip($filename);
$files = $this->getFilesFromZip($browser, $filename);
$browser->removeDownloadedFile($filename);
$expected = ['lines.txt', 'lines_lf.txt'];
$this->assertSame($expected, $files);
@ -103,14 +105,33 @@ class MailTest extends TestCase
/**
* Helper to extract files list from downloaded zip file
*/
private function getFilesFromZip($filename)
private function getFilesFromZip($browser, $filename)
{
$filename = TESTS_DIR . "downloads/{$filename}";
$filename = $browser->getDownloadedFilePath($filename);
// Give the browser a chance to finish download
if (!file_exists($filename)) {
sleep(2);
$attempts = 0;
while (!file_exists($filename)) {
if ($attempts > 9) {
throw new \Exception("File not found even after waiting period: {$filename}");
}
sleep(1);
$attempts++;
}
// Wait until the file size doesn't change anymore to be sure to have
// the full file. Under some circumstances the file apparently was used
// before its content was fully written (and sync'ed across the FS
// mounts).
$attempts = 0;
do {
if ($attempts > 9) {
throw new \Exception("File size continues to change, something is wrong! File: {$filename}");
}
$filesize1 = stat($filename)['size'];
sleep(1);
$filesize2 = stat($filename)['size'];
$attempts++;
} while ($filesize1 !== $filesize2);
$zip = new \ZipArchive();
$files = [];

11
tests/Browser/Browser.php

@ -235,7 +235,7 @@ class Browser extends \Laravel\Dusk\Browser
*/
public function readDownloadedFile($filename)
{
$filename = TESTS_DIR . "downloads/{$filename}";
$filename = $this->getDownloadedFilePath($filename);
// Give the browser a chance to finish download
$n = 0;
@ -256,7 +256,7 @@ class Browser extends \Laravel\Dusk\Browser
*/
public function removeDownloadedFile($filename)
{
@unlink(TESTS_DIR . "downloads/{$filename}");
@unlink($this->getDownloadedFilePath($filename));
return $this;
}
@ -342,4 +342,11 @@ class Browser extends \Laravel\Dusk\Browser
return $this;
}
public function getDownloadedFilePath($filename)
{
$basedir = getenv('TESTRUNNER_DOWNLOADS_DIR') ?: TESTS_DIR . 'downloads';
$basedir = rtrim($basedir, \DIRECTORY_SEPARATOR);
return $basedir . \DIRECTORY_SEPARATOR . $filename;
}
}

14
tests/Browser/TestCase.php

@ -38,7 +38,9 @@ abstract class TestCase extends PHPUnitTestCase
public static function prepare(): void
{
static::startWebServer();
static::startChromeDriver();
if (!getenv('WEBDRIVER_CONNECT_URL')) {
static::startChromeDriver();
}
}
/**
@ -60,8 +62,8 @@ abstract class TestCase extends PHPUnitTestCase
$prefs = [
'profile.default_content_settings.popups' => 0,
'download.prompt_for_download' => false,
'download.default_directory' => TESTS_DIR . 'downloads',
'downloadPath' => TESTS_DIR . 'downloads',
'download.default_directory' => getenv('BROWSER_DOWNLOADS_DIR') ?: TESTS_DIR . 'downloads',
'downloadPath' => getenv('BROWSER_DOWNLOADS_DIR') ?: TESTS_DIR . 'downloads',
];
$options->setExperimentalOption('prefs', $prefs);
@ -90,7 +92,7 @@ abstract class TestCase extends PHPUnitTestCase
}
return RemoteWebDriver::create(
'http://localhost:9515',
getenv('WEBDRIVER_CONNECT_URL') ?: 'http://localhost:9515',
DesiredCapabilities::chrome()->setCapability(
ChromeOptions::CAPABILITY,
$options
@ -108,7 +110,7 @@ abstract class TestCase extends PHPUnitTestCase
$this->app = \rcmail::get_instance();
Browser::$baseUrl = 'http://localhost:8000';
Browser::$baseUrl = getenv('SERVER_URL') ?: 'http://localhost:8000';
Browser::$storeScreenshotsAt = TESTS_DIR . 'screenshots';
Browser::$storeConsoleLogAt = TESTS_DIR . 'console';
@ -154,7 +156,7 @@ abstract class TestCase extends PHPUnitTestCase
protected static function startWebServer()
{
$path = realpath(__DIR__ . '/../../public_html');
$cmd = ['php', '-S', 'localhost:8000'];
$cmd = ['php', '-S', getenv('SERVER_BIND') ?: 'localhost:8000'];
$env = [];
static::$phpProcess = new Process($cmd, null, $env);

0
tests/Browser/downloads/.keep

Loading…
Cancel
Save