MOBILE-3320 behat: Extract app launch step
parent
b742b822dd
commit
ae0af40b10
|
@ -46,6 +46,9 @@ class behat_app extends behat_base {
|
||||||
/** @var string URL for running Ionic server */
|
/** @var string URL for running Ionic server */
|
||||||
protected $ionicurl = '';
|
protected $ionicurl = '';
|
||||||
|
|
||||||
|
/** @var bool Checks whether the app is runing a legacy version (ionic 3) */
|
||||||
|
protected $islegacy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the current OS is Windows, from the point of view of task-executing-and-killing.
|
* Checks if the current OS is Windows, from the point of view of task-executing-and-killing.
|
||||||
*
|
*
|
||||||
|
@ -67,9 +70,7 @@ class behat_app extends behat_base {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the Moodle app in the browser.
|
* Opens the Moodle app in the browser and introduces the enters the site.
|
||||||
*
|
|
||||||
* Requires JavaScript.
|
|
||||||
*
|
*
|
||||||
* @Given /^I enter the app$/
|
* @Given /^I enter the app$/
|
||||||
* @throws DriverException Issue with configuration or feature file
|
* @throws DriverException Issue with configuration or feature file
|
||||||
|
@ -77,28 +78,35 @@ class behat_app extends behat_base {
|
||||||
* @throws ExpectationException Problem with resizing window
|
* @throws ExpectationException Problem with resizing window
|
||||||
*/
|
*/
|
||||||
public function i_enter_the_app() {
|
public function i_enter_the_app() {
|
||||||
|
$this->i_launch_the_app();
|
||||||
|
$this->enter_site();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the Moodle app in the browser.
|
||||||
|
*
|
||||||
|
* @Given /^I launch the app$/
|
||||||
|
* @throws DriverException Issue with configuration or feature file
|
||||||
|
* @throws dml_exception Problem with Moodle setup
|
||||||
|
* @throws ExpectationException Problem with resizing window
|
||||||
|
*/
|
||||||
|
public function i_launch_the_app() {
|
||||||
// Check the app tag was set.
|
// Check the app tag was set.
|
||||||
if (!$this->has_tag('app')) {
|
if (!$this->has_tag('app')) {
|
||||||
throw new DriverException('Requires @app tag on scenario or feature.');
|
throw new DriverException('Requires @app tag on scenario or feature.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restart the browser and set its size.
|
|
||||||
$this->getSession()->restart();
|
|
||||||
$this->resize_window('360x720', true);
|
|
||||||
|
|
||||||
if (empty($this->ionicurl)) {
|
|
||||||
$this->ionicurl = $this->start_or_reuse_ionic();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go to page and prepare browser for app.
|
// Go to page and prepare browser for app.
|
||||||
$this->prepare_browser($this->ionicurl);
|
$this->prepare_browser();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds elements in the app.
|
* Finds elements in the app.
|
||||||
*
|
*
|
||||||
* @Then /^I should(?P<not_boolean> not)? find "(?P<text_string>(?:[^"]|\\")*)"(?: near "(?P<near_string>(?:[^"]|\\")*)")? in the app$/
|
* @Then /^I should(?P<not_boolean> not)? find "(?P<text_string>(?:[^"]|\\")*)"(?: near "(?P<near_string>(?:[^"]|\\")*)")? in the app$/
|
||||||
|
* @param string $not
|
||||||
* @param string $text
|
* @param string $text
|
||||||
|
* @param string $near
|
||||||
*/
|
*/
|
||||||
public function i_find_in_the_app($not, $text='', $near='') {
|
public function i_find_in_the_app($not, $text='', $near='') {
|
||||||
$not = !empty($not);
|
$not = !empty($not);
|
||||||
|
@ -341,75 +349,92 @@ class behat_app extends behat_base {
|
||||||
* @param string $url App URL
|
* @param string $url App URL
|
||||||
* @throws DriverException If the app fails to load properly
|
* @throws DriverException If the app fails to load properly
|
||||||
*/
|
*/
|
||||||
protected function prepare_browser(string $url) {
|
protected function prepare_browser() {
|
||||||
global $CFG;
|
// Restart the browser and set its size.
|
||||||
|
$this->getSession()->restart();
|
||||||
|
$this->resize_window('360x720', true);
|
||||||
|
|
||||||
|
if (empty($this->ionicurl)) {
|
||||||
|
$this->ionicurl = $this->start_or_reuse_ionic();
|
||||||
|
}
|
||||||
|
|
||||||
// Check whether the app is running a legacy version.
|
// Check whether the app is running a legacy version.
|
||||||
$json = @file_get_contents("$url/assets/env.json") ?: @file_get_contents("$url/config.json");
|
$json = @file_get_contents("{$this->ionicurl}/assets/env.json") ?: @file_get_contents("{$this->ionicurl}/config.json");
|
||||||
$data = json_decode($json);
|
$data = json_decode($json);
|
||||||
$appversion = $data->build->version ?? str_replace('-dev', '', $data->versionname);
|
$appversion = $data->build->version ?? str_replace('-dev', '', $data->versionname);
|
||||||
$islegacy = version_compare($appversion, '3.9.5', '<');
|
|
||||||
|
$this->islegacy = version_compare($appversion, '3.9.5', '<');
|
||||||
|
|
||||||
// Visit the Ionic URL and wait for it to load.
|
// Visit the Ionic URL and wait for it to load.
|
||||||
$this->getSession()->visit($url);
|
$this->getSession()->visit($this->ionicurl);
|
||||||
$this->spin(
|
$this->spin(function($context) {
|
||||||
function($context) use ($islegacy) {
|
$title = $context->getSession()->getPage()->find('xpath', '//title');
|
||||||
$title = $context->getSession()->getPage()->find('xpath', '//title');
|
|
||||||
if ($title) {
|
if ($title) {
|
||||||
$text = $title->getHtml();
|
$text = $title->getHtml();
|
||||||
if (
|
|
||||||
($islegacy && $text === 'Moodle Desktop') ||
|
if (
|
||||||
(!$islegacy && $text === 'Moodle App')
|
($this->islegacy && $text === 'Moodle Desktop') ||
|
||||||
) {
|
(!$this->islegacy && $text === 'Moodle App')
|
||||||
return true;
|
) {
|
||||||
}
|
return true;
|
||||||
}
|
}
|
||||||
throw new DriverException('Moodle app not found in browser');
|
}
|
||||||
}, false, 60);
|
|
||||||
|
throw new DriverException('Moodle app not found in browser');
|
||||||
|
}, false, 60);
|
||||||
|
|
||||||
// Run the scripts to install Moodle 'pending' checks.
|
// Run the scripts to install Moodle 'pending' checks.
|
||||||
$islegacyboolean = $islegacy ? 'true' : 'false';
|
$islegacyboolean = $this->islegacy ? 'true' : 'false';
|
||||||
$this->execute_script("window.BehatMoodleAppLegacy = $islegacyboolean;");
|
$this->execute_script("window.BehatMoodleAppLegacy = $islegacyboolean;");
|
||||||
$this->execute_script(file_get_contents(__DIR__ . '/app_behat_runtime.js'));
|
$this->execute_script(file_get_contents(__DIR__ . '/app_behat_runtime.js'));
|
||||||
|
|
||||||
// Wait until the site login field appears OR the main page.
|
// Assert initial page.
|
||||||
$situation = $this->spin(
|
$this->spin(function($context) {
|
||||||
function($context) use ($islegacy) {
|
$page = $context->getSession()->getPage();
|
||||||
$page = $context->getSession()->getPage();
|
$element = $page->find('xpath', '//page-core-login-site//input[@name="url"]');
|
||||||
|
|
||||||
$element = $page->find('xpath', '//page-core-login-site//input[@name="url"]');
|
if ($element) {
|
||||||
if ($element) {
|
// Wait for the onboarding modal to open, if any.
|
||||||
// Wait for the onboarding modal to open, if any.
|
$this->wait_for_pending_js();
|
||||||
$this->wait_for_pending_js();
|
|
||||||
$element = $islegacy
|
|
||||||
? $page->find('xpath', '//page-core-login-site-onboarding')
|
|
||||||
: $page->find('xpath', '//core-login-site-onboarding');
|
|
||||||
if ($element) {
|
|
||||||
$this->i_press_in_the_app('Skip');
|
|
||||||
$this->wait_for_pending_js();
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'login';
|
$element = $this->islegacy
|
||||||
}
|
? $page->find('xpath', '//page-core-login-site-onboarding')
|
||||||
|
: $page->find('xpath', '//core-login-site-onboarding');
|
||||||
|
|
||||||
$element = $page->find('xpath', '//page-core-mainmenu');
|
if ($element) {
|
||||||
if ($element) {
|
$this->i_press_in_the_app('Skip');
|
||||||
return 'mainpage';
|
}
|
||||||
}
|
|
||||||
throw new DriverException('Moodle app login URL prompt not found');
|
|
||||||
}, behat_base::get_extended_timeout(), 60);
|
|
||||||
|
|
||||||
// If it's the login page, we automatically fill in the URL and leave it on the user/pass
|
// Login screen found.
|
||||||
// page. If it's the main page, we just leave it there.
|
return true;
|
||||||
if ($situation === 'login') {
|
}
|
||||||
$this->i_set_the_field_in_the_app($islegacy ? 'campus.example.edu' : 'Your site', $CFG->wwwroot);
|
|
||||||
$this->i_press_in_the_app($islegacy ? 'Connect!' : 'Connect to your site');
|
if ($page->find('xpath', '//page-core-mainmenu')) {
|
||||||
}
|
// Main menu found.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new DriverException('Moodle app not launched properly');
|
||||||
|
}, false, 60);
|
||||||
|
|
||||||
// Continue only after JS finishes.
|
// Continue only after JS finishes.
|
||||||
$this->wait_for_pending_js();
|
$this->wait_for_pending_js();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function enter_site() {
|
||||||
|
if (!$this->is_in_login_page()) {
|
||||||
|
// Already in the site.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
global $CFG;
|
||||||
|
|
||||||
|
$this->i_set_the_field_in_the_app($this->islegacy ? 'campus.example.edu' : 'Your site', $CFG->wwwroot);
|
||||||
|
$this->i_press_in_the_app($this->islegacy ? 'Connect!' : 'Connect to your site');
|
||||||
|
$this->wait_for_pending_js();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Carries out the login steps for the app, assuming the user is on the app login page. Called
|
* Carries out the login steps for the app, assuming the user is on the app login page. Called
|
||||||
* from behat_auth.php.
|
* from behat_auth.php.
|
||||||
|
@ -536,6 +561,16 @@ class behat_app extends behat_base {
|
||||||
$this->press($text, $near);
|
$this->press($text, $near);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the current page is the login form.
|
||||||
|
*/
|
||||||
|
protected function is_in_login_page(): bool {
|
||||||
|
$page = $this->getSession()->getPage();
|
||||||
|
$logininput = $page->find('xpath', '//page-core-login-site//input[@name="url"]');
|
||||||
|
|
||||||
|
return !is_null($logininput);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clicks on / touches something that is visible in the app, near some other text.
|
* Clicks on / touches something that is visible in the app, near some other text.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue