@@ -294,6 +294,101 @@ test('openAndroidApp rejects activity override for deep link URLs', async () =>
294294 ) ;
295295} ) ;
296296
297+ test ( 'setAndroidSetting appearance dark uses cmd uimode night yes' , async ( ) => {
298+ await withMockedAdb (
299+ 'agent-device-android-appearance-dark-' ,
300+ '#!/bin/sh\nprintf "__CMD__\\n" >> "$AGENT_DEVICE_TEST_ARGS_FILE"\nprintf "%s\\n" "$@" >> "$AGENT_DEVICE_TEST_ARGS_FILE"\nexit 0\n' ,
301+ async ( { argsLogPath, device } ) => {
302+ await setAndroidSetting ( device , 'appearance' , 'dark' ) ;
303+ const lines = ( await fs . readFile ( argsLogPath , 'utf8' ) )
304+ . trim ( )
305+ . split ( '\n' )
306+ . filter ( Boolean ) ;
307+ const logged = lines . join ( ' ' ) ;
308+ assert . match ( logged , / s h e l l c m d u i m o d e n i g h t y e s / ) ;
309+ } ,
310+ ) ;
311+ } ) ;
312+
313+ test ( 'setAndroidSetting appearance toggle flips current mode' , async ( ) => {
314+ await withMockedAdb (
315+ 'agent-device-android-appearance-toggle-' ,
316+ [
317+ '#!/bin/sh' ,
318+ 'printf "__CMD__\\n" >> "$AGENT_DEVICE_TEST_ARGS_FILE"' ,
319+ 'printf "%s\\n" "$@" >> "$AGENT_DEVICE_TEST_ARGS_FILE"' ,
320+ 'if [ "$1" = "-s" ] && [ "$4" = "cmd" ] && [ "$5" = "uimode" ] && [ "$6" = "night" ] && [ -z "$7" ]; then' ,
321+ ' echo "Night mode: yes"' ,
322+ ' exit 0' ,
323+ 'fi' ,
324+ 'exit 0' ,
325+ '' ,
326+ ] . join ( '\n' ) ,
327+ async ( { argsLogPath, device } ) => {
328+ await setAndroidSetting ( device , 'appearance' , 'toggle' ) ;
329+ const lines = ( await fs . readFile ( argsLogPath , 'utf8' ) )
330+ . trim ( )
331+ . split ( '\n' )
332+ . filter ( Boolean ) ;
333+ const logged = lines . join ( ' ' ) ;
334+ assert . match ( logged , / s h e l l c m d u i m o d e n i g h t _ _ C M D _ _ / ) ;
335+ assert . match ( logged , / s h e l l c m d u i m o d e n i g h t n o / ) ;
336+ } ,
337+ ) ;
338+ } ) ;
339+
340+ test ( 'setAndroidSetting appearance toggle from auto sets dark mode' , async ( ) => {
341+ await withMockedAdb (
342+ 'agent-device-android-appearance-toggle-auto-' ,
343+ [
344+ '#!/bin/sh' ,
345+ 'printf "__CMD__\\n" >> "$AGENT_DEVICE_TEST_ARGS_FILE"' ,
346+ 'printf "%s\\n" "$@" >> "$AGENT_DEVICE_TEST_ARGS_FILE"' ,
347+ 'if [ "$1" = "-s" ] && [ "$4" = "cmd" ] && [ "$5" = "uimode" ] && [ "$6" = "night" ] && [ -z "$7" ]; then' ,
348+ ' echo "Night mode: auto"' ,
349+ ' exit 0' ,
350+ 'fi' ,
351+ 'exit 0' ,
352+ '' ,
353+ ] . join ( '\n' ) ,
354+ async ( { argsLogPath, device } ) => {
355+ await setAndroidSetting ( device , 'appearance' , 'toggle' ) ;
356+ const lines = ( await fs . readFile ( argsLogPath , 'utf8' ) )
357+ . trim ( )
358+ . split ( '\n' )
359+ . filter ( Boolean ) ;
360+ const logged = lines . join ( ' ' ) ;
361+ assert . match ( logged , / s h e l l c m d u i m o d e n i g h t y e s / ) ;
362+ } ,
363+ ) ;
364+ } ) ;
365+
366+ test ( 'setAndroidSetting appearance toggle rejects unknown current mode output' , async ( ) => {
367+ await withMockedAdb (
368+ 'agent-device-android-appearance-toggle-unknown-' ,
369+ [
370+ '#!/bin/sh' ,
371+ 'if [ "$1" = "-s" ] && [ "$4" = "cmd" ] && [ "$5" = "uimode" ] && [ "$6" = "night" ] && [ -z "$7" ]; then' ,
372+ ' echo "mode unavailable"' ,
373+ ' exit 0' ,
374+ 'fi' ,
375+ 'exit 0' ,
376+ '' ,
377+ ] . join ( '\n' ) ,
378+ async ( { device } ) => {
379+ await assert . rejects (
380+ ( ) => setAndroidSetting ( device , 'appearance' , 'toggle' ) ,
381+ ( error : unknown ) => {
382+ assert . equal ( error instanceof AppError , true ) ;
383+ assert . equal ( ( error as AppError ) . code , 'COMMAND_FAILED' ) ;
384+ assert . match ( ( error as AppError ) . message , / U n a b l e t o d e t e r m i n e c u r r e n t A n d r o i d a p p e a r a n c e / ) ;
385+ return true ;
386+ } ,
387+ ) ;
388+ } ,
389+ ) ;
390+ } ) ;
391+
297392test ( 'swipeAndroid invokes adb input swipe with duration' , async ( ) => {
298393 const tmpDir = await fs . mkdtemp ( path . join ( os . tmpdir ( ) , 'agent-device-swipe-test-' ) ) ;
299394 const adbPath = path . join ( tmpDir , 'adb' ) ;
0 commit comments