@@ -48,9 +48,6 @@ function on_app_unload(): void;
4848 */
4949class behat_app_helper extends behat_base {
5050
51- /** @var stdClass Object with data about launched Ionic instance (if any) */
52- protected static $ ionicrunning = null ;
53-
5451 /** @var array */
5552 protected static $ listeners = [];
5653
@@ -87,6 +84,21 @@ protected static function is_windows() : bool {
8784 return strtoupper (substr (PHP_OS , 0 , 3 )) === 'WIN ' ;
8885 }
8986
87+ /**
88+ * Get url of the running Ionic application.
89+ *
90+ * @return string Ionic app url.
91+ */
92+ public function get_app_url (): string {
93+ global $ CFG ;
94+
95+ if (empty ($ CFG ->behat_ionic_wwwroot )) {
96+ throw new DriverException ('$CFG->behat_ionic_wwwroot must be defined. ' );
97+ }
98+
99+ return $ CFG ->behat_ionic_wwwroot ;
100+ }
101+
90102 /**
91103 * Called from behat_hooks when a new scenario starts, if it has the app tag.
92104 *
@@ -100,8 +112,6 @@ public function start_scenario() {
100112 $ this ->notify_unload ();
101113 $ this ->apprunning = false ;
102114 }
103-
104- $ this ->ionicurl = $ this ->start_or_reuse_ionic ();
105115 }
106116
107117 /**
@@ -118,8 +128,8 @@ protected function check_behat_setup() {
118128 }
119129
120130 // Check the config settings are defined.
121- if (empty ($ CFG ->behat_ionic_wwwroot ) && empty ( $ CFG -> behat_ionic_dirroot ) ) {
122- throw new DriverException ('$CFG->behat_ionic_wwwroot or $CFG->behat_ionic_dirroot must be defined. ' );
131+ if (empty ($ CFG ->behat_ionic_wwwroot )) {
132+ throw new DriverException ('$CFG->behat_ionic_wwwroot must be defined. ' );
123133 }
124134 }
125135
@@ -171,108 +181,6 @@ protected function fix_moodle_setup() {
171181 }
172182 }
173183
174- /**
175- * Starts an Ionic server if necessary, or uses an existing one.
176- *
177- * @return string URL to Ionic server
178- * @throws DriverException If there's a system error starting Ionic
179- */
180- protected function start_or_reuse_ionic () {
181- global $ CFG ;
182-
183- if (empty ($ CFG ->behat_ionic_dirroot ) && !empty ($ CFG ->behat_ionic_wwwroot )) {
184- // Use supplied Ionic server which should already be running.
185- $ url = $ CFG ->behat_ionic_wwwroot ;
186- } else if (self ::$ ionicrunning ) {
187- // Use existing Ionic instance launched previously.
188- $ url = self ::$ ionicrunning ->url ;
189- } else {
190- // Open Ionic process in relevant path.
191- $ path = realpath ($ CFG ->behat_ionic_dirroot );
192- $ stderrfile = $ CFG ->dataroot . '/behat/ionic-stderr.log ' ;
193- $ prefix = '' ;
194- // Except on Windows, use 'exec' so that we get the pid of the actual Node process
195- // and not the shell it uses to execute. You can't do exec on Windows; there is a
196- // bypass_shell option but it is not the same thing and isn't usable here.
197- if (!self ::is_windows ()) {
198- $ prefix = 'exec ' ;
199- }
200- $ process = proc_open ($ prefix . 'ionic serve --no-interactive --no-open ' ,
201- [['pipe ' , 'r ' ], ['pipe ' , 'w ' ], ['file ' , $ stderrfile , 'w ' ]], $ pipes , $ path );
202- if ($ process === false ) {
203- throw new DriverException ('Error starting Ionic process ' );
204- }
205- fclose ($ pipes [0 ]);
206-
207- // Get pid - we will need this to kill the process.
208- $ status = proc_get_status ($ process );
209- $ pid = $ status ['pid ' ];
210-
211- // Read data from stdout until the server comes online.
212- // Note: On Windows it is impossible to read simultaneously from stderr and stdout
213- // because stream_select and non-blocking I/O don't work on process pipes, so that is
214- // why stderr was redirected to a file instead. Also, this code is simpler.
215- $ url = null ;
216- $ stdoutlog = '' ;
217- while (true ) {
218- $ line = fgets ($ pipes [1 ], 4096 );
219- if ($ line === false ) {
220- break ;
221- }
222-
223- $ stdoutlog .= $ line ;
224-
225- if (preg_match ('~^\s*Local: (http\S*)~ ' , $ line , $ matches )) {
226- $ url = $ matches [1 ];
227- break ;
228- }
229- }
230-
231- // If it failed, close the pipes and the process.
232- if (!$ url ) {
233- fclose ($ pipes [1 ]);
234- proc_close ($ process );
235- $ logpath = $ CFG ->dataroot . '/behat/ionic-start.log ' ;
236- $ stderrlog = file_get_contents ($ stderrfile );
237- @unlink ($ stderrfile );
238- file_put_contents ($ logpath ,
239- "Ionic startup log from " . date ('c ' ) .
240- "\n\n----STDOUT---- \n$ stdoutlog \n\n----STDERR---- \n$ stderrlog " );
241- throw new DriverException ('Unable to start Ionic. See ' . $ logpath );
242- }
243-
244- // Remember the URL, so we can reuse it next time, and other details so we can kill
245- // the process.
246- self ::$ ionicrunning = (object )['url ' => $ url , 'process ' => $ process , 'pipes ' => $ pipes ,
247- 'pid ' => $ pid ];
248- $ url = self ::$ ionicrunning ->url ;
249- }
250- return $ url ;
251- }
252-
253- /**
254- * Closes Ionic (if it was started) at end of test suite.
255- *
256- * @AfterSuite
257- */
258- public static function close_ionic () {
259- if (self ::$ ionicrunning ) {
260- fclose (self ::$ ionicrunning ->pipes [1 ]);
261-
262- if (self ::is_windows ()) {
263- // Using proc_terminate here does not work. It terminates the process but not any
264- // other processes it might have launched. Instead, we need to use an OS-specific
265- // mechanism to kill the process and children based on its pid.
266- exec ('taskkill /F /T /PID ' . self ::$ ionicrunning ->pid );
267- } else {
268- // On Unix this actually works, although only due to the 'exec' command inserted
269- // above.
270- proc_terminate (self ::$ ionicrunning ->process );
271- }
272- self ::$ ionicrunning = null ;
273- }
274- }
275-
276184 /**
277185 * Goes to the app page and then sets up some initial JavaScript so we can use it.
278186 *
@@ -294,12 +202,9 @@ protected function prepare_browser(array $options = []) {
294202
295203 // Reset its size.
296204 $ this ->resize_window ($ this ->windowsize , true );
297- if (empty ($ this ->ionicurl )) {
298- $ this ->ionicurl = $ this ->start_or_reuse_ionic ();
299- }
300205
301206 // Visit the Ionic URL.
302- $ this ->getSession ()->visit ($ this ->ionicurl );
207+ $ this ->getSession ()->visit ($ this ->get_app_url () );
303208 $ this ->notify_load ();
304209
305210 $ this ->apprunning = true ;
0 commit comments