3636
3737from lightning_app import LightningApp , LightningFlow
3838from lightning_app .cli .lightning_cli import run_app
39- from lightning_app .core . constants import LIGHTNING_CLOUD_PROJECT_ID
39+ from lightning_app .core import constants
4040from lightning_app .runners .multiprocess import MultiProcessRuntime
4141from lightning_app .testing .config import _Config
4242from lightning_app .utilities .app_logs import _app_logs_reader
5050from lightning_app .utilities .proxies import ProxyWorkRun
5151
5252if _is_playwright_available ():
53- import playwright
5453 from playwright .sync_api import HttpCredentials , sync_playwright
5554
5655
@@ -248,8 +247,8 @@ def run_app_in_cloud(
248247) -> Generator :
249248 """This utility is used to automate testing e2e application with lightning.ai."""
250249 # 1. Validate the provide app_folder is correct.
251- if not os .path .exists (os .path .join (app_folder , "app.py" )):
252- raise Exception ("The app folder should contain an app.py file." )
250+ if not os .path .exists (os .path .join (app_folder , app_name )):
251+ raise Exception (f "The app folder should contain an { app_name } file." )
253252 if app_folder .endswith ("/" ):
254253 app_folder = app_folder [:- 1 ]
255254
@@ -315,6 +314,14 @@ def run_app_in_cloud(
315314 process = Popen ((cmd + extra_args ), cwd = tmpdir , env = env_copy , stdout = stdout , stderr = sys .stderr )
316315 process .wait ()
317316
317+ # Fallback URL to prevent failures in case we don't get the admin URL
318+ admin_url = _Config .url
319+ with open (stdout_path ) as fo :
320+ for line in fo .readlines ():
321+ if line .startswith ("APP_LOGS_URL: " ):
322+ admin_url = line .replace ("APP_LOGS_URL: " , "" )
323+ break
324+
318325 if is_editable_mode :
319326 # Added to ensure the current code is properly uploaded.
320327 # Otherwise, it could result in un-tested PRs.
@@ -341,11 +348,20 @@ def run_app_in_cloud(
341348 record_video_dir = os .path .join (_Config .video_location , TEST_APP_NAME ),
342349 record_har_path = _Config .har_location ,
343350 )
351+
352+ client = LightningClient ()
353+ project_id = _get_project (client ).project_id
354+
355+ app = _fetch_app_by_name (client , project_id , name )
356+ app_id = app .id
357+ print (f"The Lightning App ID is: { app .id } " ) # useful for Grafana
358+
359+ if debug :
360+ process = Process (target = _print_logs , kwargs = {"app_id" : app_id })
361+ process .start ()
362+
344363 admin_page = context .new_page ()
345- print (f"The Lightning App Token is: { token } " )
346- print (f"The Lightning App user key is: { _Config .key } " )
347- print (f"The Lightning App user id is: { _Config .id } " )
348- admin_page .goto (_Config .url )
364+ admin_page .goto (admin_url )
349365 admin_page .evaluate (
350366 """data => {
351367 window.localStorage.setItem('gridUserId', data[0]);
@@ -355,59 +371,14 @@ def run_app_in_cloud(
355371 """ ,
356372 [_Config .id , _Config .key , token ],
357373 )
358- if LIGHTNING_CLOUD_PROJECT_ID :
374+ if constants . LIGHTNING_CLOUD_PROJECT_ID :
359375 admin_page .evaluate (
360376 """data => {
361377 window.localStorage.setItem('gridDefaultProjectIdOverride', JSON.stringify(data[0]));
362378 }
363379 """ ,
364- [LIGHTNING_CLOUD_PROJECT_ID ],
380+ [constants . LIGHTNING_CLOUD_PROJECT_ID ],
365381 )
366- admin_page .goto (f"{ _Config .url } /{ _Config .username } /apps" , timeout = 60 * 1000 )
367-
368- # Closing the Complete your profile dialog
369- try :
370- dialog = admin_page .locator ("text=Complete your profile" )
371- dialog .wait_for (timeout = 10 * 1000 , state = "visible" )
372- print ("'Complete your profile' dialog visible, closing it." )
373- admin_page .locator ('input[name="firstName"]' ).fill ("first" )
374- admin_page .locator ('input[name="lastName"]' ).fill ("last" )
375- admin_page .
locator (
'input[name="email"]' ).
fill (
"[email protected] " )
376- admin_page .locator ('input[name="organization"]' ).fill ("Lightning AI" )
377- button = admin_page .locator ('button:has-text("Confirm")' )
378- button .wait_for (timeout = 3 * 1000 )
379- button .click ()
380- except playwright ._impl ._api_types .TimeoutError :
381- print ("'Complete your profile' dialog not visible, skipping." )
382-
383- # Closing the Create Project dialog.
384- try :
385- project_dialog = admin_page .locator ("text=Create a project" )
386- project_dialog .wait_for (timeout = 10 * 1000 , state = "visible" )
387- print ("'Create Project' dialog visible, closing it." )
388- project_name_input = admin_page .locator ('input[type="text"]' )
389- project_name_input .fill ("Default Project" )
390- button = admin_page .locator ('button:has-text("Continue")' )
391- button .wait_for (timeout = 3 * 1000 )
392- button .click ()
393- except playwright ._impl ._api_types .TimeoutError :
394- print ("'Create Project' dialog not visible, skipping." )
395-
396- admin_page .locator (f'[data-cy="{ name } "]' ).click ()
397-
398- app_url = admin_page .url
399- admin_page .goto (app_url + "/logs" )
400-
401- client = LightningClient ()
402- project_id = _get_project (client ).project_id
403-
404- app = _fetch_app_by_name (client , project_id , name )
405- app_id = app .id
406- print (f"The Lightning App ID is: { app .id } " ) # useful for Grafana
407-
408- if debug :
409- process = Process (target = _print_logs , kwargs = {"app_id" : app_id })
410- process .start ()
411382
412383 view_page = context .new_page ()
413384 i = 1
0 commit comments