3737
3838from lightning .app import LightningApp , LightningFlow
3939from lightning .app .cli .lightning_cli import run_app
40- from lightning .app .core . constants import LIGHTNING_CLOUD_PROJECT_ID
40+ from lightning .app .core import constants
4141from lightning .app .runners .multiprocess import MultiProcessRuntime
4242from lightning .app .testing .config import _Config
4343from lightning .app .utilities .app_logs import _app_logs_reader
5151from lightning .app .utilities .proxies import ProxyWorkRun
5252
5353if _is_playwright_available ():
54- import playwright
5554 from playwright .sync_api import HttpCredentials , sync_playwright
5655
5756
@@ -245,8 +244,8 @@ def run_app_in_cloud(
245244) -> Generator :
246245 """This utility is used to automate testing e2e application with lightning.ai."""
247246 # 1. Validate the provide app_folder is correct.
248- if not os .path .exists (os .path .join (app_folder , "app.py" )):
249- raise Exception ("The app folder should contain an app.py file." )
247+ if not os .path .exists (os .path .join (app_folder , app_name )):
248+ raise Exception (f "The app folder should contain an { app_name } file." )
250249 if app_folder .endswith ("/" ):
251250 app_folder = app_folder [:- 1 ]
252251
@@ -312,6 +311,14 @@ def run_app_in_cloud(
312311 process = Popen ((cmd + extra_args ), cwd = tmpdir , env = env_copy , stdout = stdout , stderr = sys .stderr )
313312 process .wait ()
314313
314+ # Fallback URL to prevent failures in case we don't get the admin URL
315+ admin_url = _Config .url
316+ with open (stdout_path ) as fo :
317+ for line in fo .readlines ():
318+ if line .startswith ("APP_LOGS_URL: " ):
319+ admin_url = line .replace ("APP_LOGS_URL: " , "" )
320+ break
321+
315322 if is_editable_mode :
316323 # Added to ensure the current code is properly uploaded.
317324 # Otherwise, it could result in un-tested PRs.
@@ -338,11 +345,20 @@ def run_app_in_cloud(
338345 record_video_dir = os .path .join (_Config .video_location , TEST_APP_NAME ),
339346 record_har_path = _Config .har_location ,
340347 )
348+
349+ client = LightningClient ()
350+ project_id = _get_project (client ).project_id
351+
352+ app = _fetch_app_by_name (client , project_id , name )
353+ app_id = app .id
354+ print (f"The Lightning App ID is: { app .id } " ) # useful for Grafana
355+
356+ if debug :
357+ process = Process (target = _print_logs , kwargs = {"app_id" : app_id })
358+ process .start ()
359+
341360 admin_page = context .new_page ()
342- print (f"The Lightning App Token is: { token } " )
343- print (f"The Lightning App user key is: { _Config .key } " )
344- print (f"The Lightning App user id is: { _Config .id } " )
345- admin_page .goto (_Config .url )
361+ admin_page .goto (admin_url )
346362 admin_page .evaluate (
347363 """data => {
348364 window.localStorage.setItem('gridUserId', data[0]);
@@ -352,59 +368,14 @@ def run_app_in_cloud(
352368 """ ,
353369 [_Config .id , _Config .key , token ],
354370 )
355- if LIGHTNING_CLOUD_PROJECT_ID :
371+ if constants . LIGHTNING_CLOUD_PROJECT_ID :
356372 admin_page .evaluate (
357373 """data => {
358374 window.localStorage.setItem('gridDefaultProjectIdOverride', JSON.stringify(data[0]));
359375 }
360376 """ ,
361- [LIGHTNING_CLOUD_PROJECT_ID ],
377+ [constants . LIGHTNING_CLOUD_PROJECT_ID ],
362378 )
363- admin_page .goto (f"{ _Config .url } /{ _Config .username } /apps" , timeout = 60 * 1000 )
364-
365- # Closing the Complete your profile dialog
366- try :
367- dialog = admin_page .locator ("text=Complete your profile" )
368- dialog .wait_for (timeout = 10 * 1000 , state = "visible" )
369- print ("'Complete your profile' dialog visible, closing it." )
370- admin_page .locator ('input[name="firstName"]' ).fill ("first" )
371- admin_page .locator ('input[name="lastName"]' ).fill ("last" )
372- admin_page .
locator (
'input[name="email"]' ).
fill (
"[email protected] " )
373- admin_page .locator ('input[name="organization"]' ).fill ("Lightning AI" )
374- button = admin_page .locator ('button:has-text("Confirm")' )
375- button .wait_for (timeout = 3 * 1000 )
376- button .click ()
377- except playwright ._impl ._api_types .TimeoutError :
378- print ("'Complete your profile' dialog not visible, skipping." )
379-
380- # Closing the Create Project dialog.
381- try :
382- project_dialog = admin_page .locator ("text=Create a project" )
383- project_dialog .wait_for (timeout = 10 * 1000 , state = "visible" )
384- print ("'Create Project' dialog visible, closing it." )
385- project_name_input = admin_page .locator ('input[type="text"]' )
386- project_name_input .fill ("Default Project" )
387- button = admin_page .locator ('button:has-text("Continue")' )
388- button .wait_for (timeout = 3 * 1000 )
389- button .click ()
390- except playwright ._impl ._api_types .TimeoutError :
391- print ("'Create Project' dialog not visible, skipping." )
392-
393- admin_page .locator (f'[data-cy="{ name } "]' ).click ()
394-
395- app_url = admin_page .url
396- admin_page .goto (app_url + "/logs" )
397-
398- client = LightningClient ()
399- project_id = _get_project (client ).project_id
400-
401- app = _fetch_app_by_name (client , project_id , name )
402- app_id = app .id
403- print (f"The Lightning App ID is: { app .id } " ) # useful for Grafana
404-
405- if debug :
406- process = Process (target = _print_logs , kwargs = {"app_id" : app_id })
407- process .start ()
408379
409380 view_page = context .new_page ()
410381 i = 1
0 commit comments