diff --git a/.circleci/.gitignore b/.circleci/.gitignore
new file mode 100644
index 0000000000..b0e880b773
--- /dev/null
+++ b/.circleci/.gitignore
@@ -0,0 +1,4 @@
+.DS_Store
+local.test
+local.env
+local.ssh
diff --git a/.circleci/behat.yml b/.circleci/behat.yml
new file mode 100644
index 0000000000..12c5964322
--- /dev/null
+++ b/.circleci/behat.yml
@@ -0,0 +1,14 @@
+# behat.yml
+default:
+ suites:
+ default:
+ paths:
+ - features
+ contexts:
+ - Behat\MinkExtension\Context\MinkContext
+ - AdminLogIn
+ - ResponseHeader
+ extensions:
+ Behat\MinkExtension:
+ # base_url set by ENV
+ goutte: ~
diff --git a/.circleci/cleanup.sh b/.circleci/cleanup.sh
new file mode 100755
index 0000000000..43f85c472a
--- /dev/null
+++ b/.circleci/cleanup.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+# Echo commands as they are executed, but don't allow errors to stop the script.
+set -x
+
+if [ -z "$TERMINUS_SITE" ] || [ -z "$TERMINUS_ENV" ]; then
+ echo "TERMINUS_SITE and TERMINUS_ENV environment variables must be set"
+ exit 1
+fi
+
+# Only delete old environments if there is a pattern defined to
+# match environments eligible for deletion. Otherwise, delete the
+# current multidev environment immediately.
+#
+# To use this feature, set MULTIDEV_DELETE_PATTERN to '^ci-' or similar
+# in the CI server environment variables.
+if [ -z "$MULTIDEV_DELETE_PATTERN" ] ; then
+ terminus env:delete $TERMINUS_SITE.$TERMINUS_ENV --delete-branch --yes
+ exit 0
+fi
+
+# List all but the newest two environments.
+OLDEST_ENVIRONMENTS=$(terminus env:list "$TERMINUS_SITE" --format=list | grep -v dev | grep -v test | grep -v live | sort -k2 | grep "$MULTIDEV_DELETE_PATTERN" | sed -e '$d' | sed -e '$d')
+
+# Exit if there are no environments to delete
+if [ -z "$OLDEST_ENVIRONMENTS" ] ; then
+ exit 0
+fi
+
+# Go ahead and delete the oldest environments.
+for ENV_TO_DELETE in $OLDEST_ENVIRONMENTS ; do
+ terminus env:delete $TERMINUS_SITE.$ENV_TO_DELETE --delete-branch --yes
+done
diff --git a/.circleci/config.yml b/.circleci/config.yml
new file mode 100644
index 0000000000..e0dc6fb359
--- /dev/null
+++ b/.circleci/config.yml
@@ -0,0 +1,58 @@
+test-defaults: &test-defaults
+ docker:
+ - image: quay.io/pantheon-public/terminus-plugin-test:1.x
+ working_directory: ~/work/wp
+ environment:
+ TZ: "/usr/share/zoneinfo/America/Los_Angeles"
+ TERM: dumb
+
+merge-defaults: &merge-defaults
+ docker:
+ - image: quay.io/getpantheon/upstream-update-build:1.x
+ working_directory: ~/work/wp
+ environment:
+ TZ: "/usr/share/zoneinfo/America/Los_Angeles"
+ TERM: dumb
+
+version: 2
+jobs:
+ test:
+ <<: *test-defaults
+ steps:
+ - checkout
+ - run:
+ name: Set up environment
+ command: ./.circleci/set-up-globals.sh
+ - run:
+ name: Prepare
+ command: ./.circleci/prepare.sh
+ - run:
+ name: Test
+ command: ./.circleci/test.sh --strict
+ - run:
+ name: Cleanup
+ command: ./.circleci/cleanup.sh
+ - run:
+ name: Confirm that it is safe to merge
+ command: ./.circleci/confirm-safety.sh
+ merge:
+ <<: *merge-defaults
+ steps:
+ - checkout
+ - run:
+ # https://github.com/pantheon-systems/upstream-update-build/blob/1.x/bin/automerge.sh
+ name: Merge the default branch back to the master branch
+ command: automerge.sh
+
+workflows:
+ version: 2
+ wordpress:
+ jobs:
+ - test
+ - merge:
+ requires:
+ - test
+ filters:
+ branches:
+ only:
+ - default
diff --git a/.circleci/confirm-safety.sh b/.circleci/confirm-safety.sh
new file mode 100755
index 0000000000..1a6f717101
--- /dev/null
+++ b/.circleci/confirm-safety.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+#
+# The purpose of this script is to examine the base branch that this PR is
+# set to merge into by usig the GitHub API. We are only querying a public
+# repo here, so we do not need to use the GITHUB_TOKEN.
+#
+
+# Exit if we are not running on Circle CI.
+if [ -z "$CIRCLECI" ] ; then
+ exit 0
+fi
+
+# We only need to make this check for branches forked from default (right) / master (wrong).
+# Skip the test for the default branch. (The .circleci directory will never be added to the master branch).
+if [ "$CIRCLE_BRANCH" == "default" ] ; then
+ exit 0
+fi
+
+# We cannot continue unless we have a pull request.
+if [ -z "$CIRCLE_PULL_REQUEST" ] ; then
+ echo "No CIRCLE_PULL_REQUEST defined; please create a pull request."
+ exit 1
+fi
+
+# CIRCLE_PULL_REQUEST=https://github.com/ORG/PROJECT/pull/NUMBER
+PR_NUMBER=$(echo $CIRCLE_PULL_REQUEST | sed -e 's#.*/pull/##')
+
+# Display the API call we are using
+echo curl https://api.github.com/repos/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/pulls/$PR_NUMBER
+
+base=$(curl https://api.github.com/repos/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/pulls/$PR_NUMBER 2>/dev/null | jq .base.ref)
+
+echo "The base branch is $base"
+
+# If the PR merges into 'default', then it is safe to merge.
+if [ "$base" == '"default"' ] ; then
+ echo "It is safe to merge this PR into the $base branch"
+ exit 0
+fi
+
+# Force a test failure if the PR's base is the master branch.
+if [ "$base" == '"master"' ] ; then
+ echo "ERROR: merging this PR into the $base branch is not allowed. Change the base branch for the PR to merge into the \"default\" branch instead."
+ exit 1
+fi
+
+echo "Merging probably okay, if you are merging one PR into another. Use caution; do not merge to the \"master\" branch."
diff --git a/.circleci/features/0-install.feature b/.circleci/features/0-install.feature
new file mode 100644
index 0000000000..792a9b452a
--- /dev/null
+++ b/.circleci/features/0-install.feature
@@ -0,0 +1,59 @@
+Feature: Install WordPress through the web UI
+
+ @upstreamonly
+ Scenario: Install WordPress with the en_US locale
+ When I go to "/"
+ Then print current URL
+ And I should be on "/wp-admin/install.php"
+
+ When I press "language-continue"
+ Then print current URL
+ And I should be on "/wp-admin/install.php?step=1"
+ And I should see "Welcome to the famous five-minute WordPress installation process!"
+
+ When I fill in "weblog_title" with "Pantheon WordPress Upstream"
+ And I fill in "user_name" with the command line global variable: "WORDPRESS_ADMIN_USERNAME"
+ And I fill in "admin_password" with the command line global variable: "WORDPRESS_ADMIN_PASSWORD"
+ And I fill in "admin_password2" with the command line global variable: "WORDPRESS_ADMIN_PASSWORD"
+ And I check "pw_weak"
+ And I fill in "admin_email" with "wordpress-upstream@getpantheon.com"
+ And I press "submit"
+ Then print current URL
+ And I should be on "/wp-admin/install.php?step=2"
+ And I should see "WordPress has been installed."
+ And I follow "Log In"
+ And I fill in "Username or Email Address" with the command line global variable: "WORDPRESS_ADMIN_USERNAME"
+ And I fill in "Password" with the command line global variable: "WORDPRESS_ADMIN_PASSWORD"
+ And I press "Log In"
+ And I should see "Welcome to WordPress!"
+
+ Scenario: Attempting to install WordPress a second time should error
+ When I go to "/wp-admin/install.php"
+ Then I should see "You appear to have already installed WordPress."
+
+ Scenario: Verify the active theme is Twenty-Something (no point breaking every year for no good reason)
+ When I go to "/"
+ Then the response should contain "minkContext->visit('wp-login.php');
+ $this->minkContext->fillField('log', getenv('WORDPRESS_ADMIN_USERNAME'));
+ $this->minkContext->fillField('pwd', getenv('WORDPRESS_ADMIN_PASSWORD'));
+ $this->minkContext->pressButton('wp-submit');
+ $this->minkContext->assertPageAddress("wp-admin/");
+ }
+
+ /**
+ * Fills in form field with specified id|name|label|value
+ * Example: When I fill in "admin_password2" with the command line global variable: "WORDPRESS_ADMIN_PASSWORD"
+ *
+ * @When I fill in :arg1 with the command line global variable: :arg2
+ */
+ public function fillFieldWithGlobal($field, $value)
+ {
+ $this->minkContext->fillField($field, getenv($value));
+ }
+}
diff --git a/.circleci/features/bootstrap/ResponseHeader.php b/.circleci/features/bootstrap/ResponseHeader.php
new file mode 100644
index 0000000000..ba463d366b
--- /dev/null
+++ b/.circleci/features/bootstrap/ResponseHeader.php
@@ -0,0 +1,46 @@
+(?:[^"]|\\")*)" should be "(?P(?:[^"]|\\")*)"$/
+ */
+ public function assertResponseHeader($name, $value)
+ {
+ $this->assertSession()->responseHeaderEquals($name, $value);
+ }
+
+ /**
+ * Checks, that current page response header is not equal to specified.
+ *
+ * @Then /^the response header "(?P(?:[^"]|\\")*)" should not be "(?P(?:[^"]|\\")*)"$/
+ */
+ public function assertResponseHeaderIsNot($name, $value)
+ {
+ $this->assertSession()->responseHeaderNotEquals($name, $value);
+ }
+
+ /**
+ * Checks, that current page response header contains specified value.
+ *
+ * @Then /^the response header "(?P(?:[^"]|\\")*)" should contain "(?P(?:[^"]|\\")*)"$/
+ */
+ public function assertResponseHeaderContains($name, $value)
+ {
+ $this->assertSession()->responseHeaderContains($name, $value);
+ }
+ /**
+ * Checks, that current page response header does not contain specified value.
+ *
+ * @Then /^the response header "(?P(?:[^"]|\\")*)" should not contain "(?P(?:[^"]|\\")*)"$/
+ */
+ public function assertResponseHeaderNotContains($name, $value)
+ {
+ $this->assertSession()->responseHeaderNotContains($name, $value);
+ }
+
+}
diff --git a/.circleci/features/options.feature b/.circleci/features/options.feature
new file mode 100644
index 0000000000..ac2e02d9b1
--- /dev/null
+++ b/.circleci/features/options.feature
@@ -0,0 +1,27 @@
+Feature: Manage WordPress options
+
+ Background:
+ Given I log in as an admin
+
+ Scenario: Update the site tagline
+ When I go to "/"
+ Then I should see "Just another WordPress site" in the ".site-description" element
+ And I should not see "Pantheon upstream testing site" in the ".site-description" element
+
+ When I go to "/wp-admin/options-general.php"
+ And I fill in "blogdescription" with "Pantheon upstream testing site"
+ And I press "submit"
+ Then I should see "Settings saved."
+
+ When I go to "/"
+ Then I should see "Pantheon upstream testing site" in the ".site-description" element
+ Then I should not see "Just another WordPress site" in the ".site-description" element
+
+ When I go to "/wp-admin/options-general.php"
+ And I fill in "blogdescription" with "Just another WordPress site"
+ And I press "submit"
+ Then I should see "Settings saved."
+
+ When I go to "/"
+ Then I should see "Just another WordPress site" in the ".site-description" element
+ And I should not see "Pantheon upstream testing site" in the ".site-description" element
diff --git a/.circleci/features/pantheon-logged-out.feature b/.circleci/features/pantheon-logged-out.feature
new file mode 100644
index 0000000000..1cf898edf8
--- /dev/null
+++ b/.circleci/features/pantheon-logged-out.feature
@@ -0,0 +1,7 @@
+Feature: Verify various Pantheon features as a logged-out user
+
+ Scenario: Cache-Control should default to TTL=600
+ When I go to "/"
+ And the response header "Cache-Control" should be "public, max-age=600"
+ And the response header "Pragma" should not contain "no-cache"
+
diff --git a/.circleci/features/pantheon.feature b/.circleci/features/pantheon.feature
new file mode 100644
index 0000000000..49c94fba46
--- /dev/null
+++ b/.circleci/features/pantheon.feature
@@ -0,0 +1,35 @@
+Feature: Perform Pantheon-specific actions
+
+ Background:
+ Given I log in as an admin
+
+ Scenario: Change the cache TTL
+ When I go to "/wp-admin/options-general.php?page=pantheon-cache"
+ Then I should see "Pantheon Page Cache"
+ And the "pantheon-cache[default_ttl]" field should contain "600"
+
+ When I fill in "pantheon-cache[default_ttl]" with "300"
+ And I press "Update TTL"
+ Then I should see "Settings saved."
+ And the "pantheon-cache[default_ttl]" field should contain "300"
+
+ When I fill in "pantheon-cache[default_ttl]" with "600"
+ And I press "Update TTL"
+ Then I should see "Settings saved."
+ And the "pantheon-cache[default_ttl]" field should contain "600"
+
+ Scenario: Clear the site cache
+ When I go to "/wp-admin/options-general.php?page=pantheon-cache"
+ Then I should see "Clear Site Cache"
+ And I should not see "Site cache flushed."
+
+ When I press "Clear Cache"
+ Then print current URL
+ And I should be on "/wp-admin/options-general.php?page=pantheon-cache&cache-cleared=true"
+ And I should see "Site cache flushed." in the ".updated" element
+
+ Scenario: Verify the Pantheon MU plugin is present
+ When I go to "/wp-admin/plugins.php?plugin_status=mustuse"
+ Then I should see "Files in the /wp-content/mu-plugins directory are executed automatically." in the ".tablenav" element
+ And I should see "Pantheon" in the "#the-list" element
+ And I should see "Building on Pantheon's and WordPress's strengths, together." in the "#the-list" element
diff --git a/.circleci/features/plugins.feature b/.circleci/features/plugins.feature
new file mode 100644
index 0000000000..5e7975c8c0
--- /dev/null
+++ b/.circleci/features/plugins.feature
@@ -0,0 +1,33 @@
+Feature: Manage WordPress plugins
+
+ Background:
+ Given I log in as an admin
+
+ @upstreamonly
+ Scenario: Install, activate, deactivate, and delete a plugin
+ When I go to "/wp-admin/plugin-install.php?tab=search&s=hello+dolly"
+ And I follow "Hello Dolly"
+ Then print current URL
+ Then I should see "Hello Dolly" in the "#plugin-information-title" element
+
+ When I follow "Install Now"
+ Then print current URL
+ And I should see "Successfully installed the plugin Hello Dolly"
+
+ When I follow "Activate Plugin"
+ Then print current URL
+ And I should see "Plugin activated." in the "#message" element
+ And I should see a "#dolly" element
+ And I should see "1 item" in the ".displaying-num" element
+
+ When I follow "Deactivate"
+ Then print current URL
+ And I should see "Plugin deactivated." in the "#message" element
+
+ When I follow "Delete"
+ Then I should see "You are about to remove the following plugin:"
+
+ When I press "submit"
+ Then print current URL
+ And I should see "The selected plugin has been deleted." in the "#message" element
+ And I should see "No plugins are currently available."
diff --git a/.circleci/features/terms.feature b/.circleci/features/terms.feature
new file mode 100644
index 0000000000..fa0c4455fb
--- /dev/null
+++ b/.circleci/features/terms.feature
@@ -0,0 +1,12 @@
+Feature: Manage WordPress terms
+
+ Background:
+ Given I log in as an admin
+
+ Scenario: Create a new tag
+ When I go to "/wp-admin/edit-tags.php?taxonomy=post_tag"
+ And I fill in "tag-name" with "Pantheon Testing Tag"
+ And I press "submit"
+ Then print current URL
+ And I should see "Tag added."
+ And I should see "Pantheon Testing Tag"
diff --git a/.circleci/features/themes.feature b/.circleci/features/themes.feature
new file mode 100644
index 0000000000..25ed5642e6
--- /dev/null
+++ b/.circleci/features/themes.feature
@@ -0,0 +1 @@
+Feature: Manage WordPress themes
diff --git a/.circleci/features/users.feature b/.circleci/features/users.feature
new file mode 100644
index 0000000000..c07b34f60a
--- /dev/null
+++ b/.circleci/features/users.feature
@@ -0,0 +1,40 @@
+Feature: Manage WordPress users
+
+ Background:
+ Given I log in as an admin
+
+ Scenario: User create, update and delete
+ When I go to "/wp-admin/user-new.php"
+ And I fill in "user_login" with "pantheontestuser"
+ And I fill in "email" with "test@example.com"
+ And I fill in "pass1" with "password"
+ And I fill in "pass2" with "password"
+ And I press "createuser"
+ Then print current URL
+ And I should be on "/wp-admin/users.php?id=2"
+ And I should see "New user created." in the "#message" element
+ And I should see "2 items" in the ".displaying-num" element
+
+ When I go to "/wp-admin/users.php"
+ And I follow "pantheontestuser"
+ Then print current URL
+ And I should be on "/wp-admin/user-edit.php?user_id=2&wp_http_referer=%2Fwp-admin%2Fusers.php"
+ And the "first_name" field should not contain "Pantheon Test"
+
+ When I fill in "first_name" with "Pantheon Test"
+ And I press "submit"
+ Then print current URL
+ And I should be on "/wp-admin/user-edit.php?user_id=2&wp_http_referer=%2Fwp-admin%2Fusers.php"
+ And I should see "User updated." in the "#message" element
+ And the "first_name" field should contain "Pantheon Test"
+
+ When I go to "/wp-admin/users.php"
+ And I follow "Delete"
+ Then print current URL
+ And I should see "You have specified this user for deletion:"
+
+ When I press "submit"
+ Then print current URL
+ And I should be on "/wp-admin/users.php?delete_count=1"
+ And I should see "User deleted." in the "#message" element
+ And I should see "1 item" in the ".displaying-num" element
diff --git a/.circleci/local.test.dist b/.circleci/local.test.dist
new file mode 100755
index 0000000000..1a15254072
--- /dev/null
+++ b/.circleci/local.test.dist
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# Copy to local.test and customize
+circleci \
+ -e CIRCLE_BUILD_NUM=0 \
+ -e TERMINUS_TOKEN=$TERMINUS_TOKEN \
+ -e TERMINUS_SITE=$TERMINUS_SITE \
+ -e TERMINUS_ENV=ci-$CIRCLE_BUILD_NUM \
+ -e TERMINUS_HIDE_UPDATE_MESSAGE=1 \
+ -e WORDPRESS_ADMIN_USERNAME=admin \
+ -e WORDPRESS_ADMIN_PASSWORD=$ADMIN_PASSWORD \
+ build --job test
diff --git a/.circleci/prepare.sh b/.circleci/prepare.sh
new file mode 100755
index 0000000000..92e982aae6
--- /dev/null
+++ b/.circleci/prepare.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+###
+# Prepare a Pantheon site environment for the Behat test suite, by pushing the
+# requested upstream branch to the environment. This script is architected
+# such that it can be run a second time if a step fails.
+###
+
+set -ex
+
+if [ -z "$TERMINUS_SITE" ] || [ -z "$TERMINUS_ENV" ]; then
+ echo "TERMINUS_SITE and TERMINUS_ENV environment variables must be set"
+ exit 1
+fi
+
+###
+# Create a new environment for this particular test run.
+###
+terminus --yes env:info $TERMINUS_SITE.$TERMINUS_ENV 2>/dev/null || terminus --yes env:create $TERMINUS_SITE.dev $TERMINUS_ENV
+terminus --yes env:wipe $TERMINUS_SITE.$TERMINUS_ENV
+
+###
+# Get all necessary environment details.
+###
+PANTHEON_GIT_URL=$(terminus connection:info $TERMINUS_SITE.$TERMINUS_ENV --field=git_url)
+PANTHEON_SITE_URL="$TERMINUS_ENV-$TERMINUS_SITE.pantheonsite.io"
+BASH_DIR="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+###
+# Switch to git mode for pushing the files up
+###
+terminus --yes connection:set $TERMINUS_SITE.$TERMINUS_ENV git
+
+###
+# Push the upstream branch to the environment
+###
+git remote add pantheon $PANTHEON_GIT_URL
+git push -f pantheon $CIRCLE_BRANCH:$TERMINUS_ENV
+
+###
+# Switch to SFTP mode so the site can install plugins and themes
+###
+terminus --yes connection:set $TERMINUS_SITE.$TERMINUS_ENV sftp
diff --git a/.circleci/set-up-globals.sh b/.circleci/set-up-globals.sh
new file mode 100755
index 0000000000..4e689efe8c
--- /dev/null
+++ b/.circleci/set-up-globals.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+
+# Create a local .ssh directory if needed & available
+SELF_DIRNAME="`dirname -- "$0"`"
+[ -d "$HOME/.ssh" ] || [ ! -d "$SELF_DIRNAME/local.ssh" ] || cp -R "$SELF_DIRNAME/local.ssh" "$HOME/.ssh"
+
+# If an admin password has not been defined, write one to ~/WORDPRESS_ADMIN_PASSWORD
+if [ ! -f ~/WORDPRESS_ADMIN_PASSWORD ] && [ -z "$WORDPRESS_ADMIN_PASSWORD" ] ; then
+ echo $(openssl rand -hex 8) > ~/WORDPRESS_ADMIN_PASSWORD
+fi
+
+# If an admin password has not been defined, read it from ~/WORDPRESS_ADMIN_PASSWORD
+if [ ! -f ~/WORDPRESS_ADMIN_PASSWORD ] && [ -z "$WORDPRESS_ADMIN_PASSWORD" ] ; then
+ WORDPRESS_ADMIN_PASSWORD="$(cat ~/WORDPRESS_ADMIN_PASSWORD)"
+fi
+
+#=====================================================================================================================
+# EXPORT needed environment variables
+#
+# Circle CI 2.0 does not yet expand environment variables so they have to be manually EXPORTed
+# Once environment variables can be expanded this section can be removed
+# See: https://discuss.circleci.com/t/unclear-how-to-work-with-user-variables-circleci-provided-env-variables/12810/11
+# See: https://discuss.circleci.com/t/environment-variable-expansion-in-working-directory/11322
+# See: https://discuss.circleci.com/t/circle-2-0-global-environment-variables/8681
+#=====================================================================================================================
+mkdir -p $(dirname $BASH_ENV)
+touch $BASH_ENV
+(
+ echo 'export PATH=$PATH:$HOME/bin'
+ echo 'export TERMINUS_HIDE_UPDATE_MESSAGE=1'
+ echo 'export TERMINUS_ENV=ci-$CIRCLE_BUILD_NUM'
+ echo 'export WORDPRESS_ADMIN_USERNAME=pantheon'
+ echo "export WORDPRESS_ADMIN_PASSWORD=$WORDPRESS_ADMIN_PASSWORD"
+) >> $BASH_ENV
+source $BASH_ENV
+
+echo "Test site is $TERMINUS_SITE.$TERMINUS_ENV"
+echo "Logging in with a machine token:"
+terminus auth:login -n --machine-token="$TERMINUS_TOKEN"
+terminus whoami
+touch $HOME/.ssh/config
+echo "StrictHostKeyChecking no" >> "$HOME/.ssh/config"
+git config --global user.email "$GIT_EMAIL"
+git config --global user.name "Circle CI"
+# Ignore file permissions.
+git config --global core.fileMode false
diff --git a/.circleci/test.sh b/.circleci/test.sh
new file mode 100755
index 0000000000..781b41a592
--- /dev/null
+++ b/.circleci/test.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+###
+# Execute the Behat test suite against a prepared Pantheon site environment.
+###
+
+set -ex
+
+SELF_DIRNAME="`dirname -- "$0"`"
+
+# Require a target site
+if [ -z "$TERMINUS_SITE" ] || [ -z "$TERMINUS_ENV" ]; then
+ echo "TERMINUS_SITE and TERMINUS_ENV environment variables must be set"
+ exit 1
+fi
+
+# Require admin username and password
+if [ -z "$WORDPRESS_ADMIN_USERNAME" ] || [ -z "$WORDPRESS_ADMIN_PASSWORD" ]; then
+ echo "WORDPRESS_ADMIN_USERNAME and WORDPRESS_ADMIN_PASSWORD environment variables must be set"
+ exit 1
+fi
+
+export BEHAT_PARAMS='{"extensions" : {"Behat\\MinkExtension" : {"base_url" : "http://'$TERMINUS_ENV'-'$TERMINUS_SITE'.pantheonsite.io"} }}'
+
+# We expect 'behat' to be in our PATH. Our container symlinks it at /usr/local/bin
+cd $SELF_DIRNAME && behat --config=behat.yml $*