@@ -162,6 +162,7 @@ export class DebugConfigProvider implements DebugConfigurationProvider {
162162 // Some helpers for conditions below.
163163 const isAnyFlutter = debugType === DebuggerType . Flutter || debugType === DebuggerType . Web ;
164164 const isStandardFlutter = debugType === DebuggerType . Flutter ;
165+ const isIntegrationTest = debugConfig . program && isInsideFolderNamed ( debugConfig . program as string , "integration_test" ) ;
165166 const isTest = debugConfig . program && isTestFileOrFolder ( debugConfig . program as string ) ;
166167 const argsHaveTestNameFilter = isTest && debugConfig . args && ( debugConfig . args . indexOf ( "--name" ) !== - 1 || debugConfig . args . indexOf ( "--pname" ) !== - 1 ) ;
167168
@@ -177,14 +178,22 @@ export class DebugConfigProvider implements DebugConfigurationProvider {
177178 debugType = DebuggerType . PubTest ;
178179 break ;
179180 case DebuggerType . Flutter :
180- if ( ! debugConfig . runTestsOnDevice || argsHaveTestNameFilter ) {
181- if ( debugConfig . runTestsOnDevice && argsHaveTestNameFilter ) {
182- vs . window . showWarningMessage ( "Running with 'flutter test' as 'runTestsOnDevice' is not supported for individual tests." ) ;
183- logger . info ( `runTestsOnDevice is set but args have test filter so will still use Flutter` ) ;
184- }
181+ if ( isIntegrationTest ) {
182+ // Integration tests always use "flutter test".
185183 debugType = DebuggerType . FlutterTest ;
186- } else {
184+ } else if ( debugConfig . runTestsOnDevice && argsHaveTestNameFilter ) {
185+ // Non-integration tests set to run on device but have a test name filter will also have
186+ // to run with "flutter test".
187+ vs . window . showWarningMessage ( "Running with 'flutter test' as 'runTestsOnDevice' is not supported for individual tests." ) ;
188+ logger . info ( `runTestsOnDevice is set but args have test filter so will still use Flutter` ) ;
189+ debugType = DebuggerType . FlutterTest ;
190+ } else if ( debugConfig . runTestsOnDevice ) {
191+ // Anything else (eg. Non-integration tests without a test name filter) is allowed to
192+ // run on a device if specified.
187193 logger . info ( `runTestsOnDevice is set, so will use Flutter instead of FlutterTest` ) ;
194+ } else {
195+ // Otherwise, default is to use "flutter test".
196+ debugType = DebuggerType . FlutterTest ;
188197 }
189198 break ;
190199 case DebuggerType . Web :
@@ -248,29 +257,33 @@ export class DebugConfigProvider implements DebugConfigurationProvider {
248257 if ( token && token . isCancellationRequested )
249258 return ;
250259
251- let deviceToLaunchOn = this . deviceManager ?. getDevice ( debugConfig . deviceId ) || this . deviceManager ?. currentDevice ;
252260
253261 // Ensure we have a device if required.
254- if ( debugType === DebuggerType . Flutter && this . deviceManager && this . daemon && debugConfig . deviceId !== "flutter-tester" ) {
255- let supportedPlatforms = this . daemon . capabilities . providesPlatformTypes && debugConfig . cwd
256- ? ( await this . daemon . getSupportedPlatforms ( debugConfig . cwd ) ) . platforms
257- : [ ] ;
258-
259- // If the current device is not valid, prompt the user.
260- if ( ! this . deviceManager . isSupported ( supportedPlatforms , deviceToLaunchOn ) )
261- deviceToLaunchOn = await this . deviceManager . showDevicePicker ( supportedPlatforms ) ;
262-
263- // Refresh the supported platforms, as the we may have enabled new platforms during
264- // the call to showDevicePicker.
265- supportedPlatforms = this . daemon . capabilities . providesPlatformTypes && debugConfig . cwd
266- ? ( await this . daemon . getSupportedPlatforms ( debugConfig . cwd ) ) . platforms
267- : [ ] ;
268-
269- // If we still don't have a valid device, show an error.
270- if ( ! this . deviceManager . isSupported ( supportedPlatforms , deviceToLaunchOn ) ) {
271- logger . warn ( "Unable to launch due to no active device" ) ;
272- window . showInformationMessage ( "Cannot launch without an active device" ) ;
273- return undefined ; // undefined means silent (don't open launch.json).
262+ let deviceToLaunchOn ;
263+ const requiresDevice = debugType === DebuggerType . Flutter || ( DebuggerType . FlutterTest && isIntegrationTest ) ;
264+ if ( requiresDevice ) {
265+ deviceToLaunchOn = this . deviceManager ?. getDevice ( debugConfig . deviceId ) || this . deviceManager ?. currentDevice ;
266+ if ( this . deviceManager && this . daemon && debugConfig . deviceId !== "flutter-tester" ) {
267+ let supportedPlatforms = this . daemon . capabilities . providesPlatformTypes && debugConfig . cwd
268+ ? ( await this . daemon . getSupportedPlatforms ( debugConfig . cwd ) ) . platforms
269+ : [ ] ;
270+
271+ // If the current device is not valid, prompt the user.
272+ if ( ! this . deviceManager . isSupported ( supportedPlatforms , deviceToLaunchOn ) )
273+ deviceToLaunchOn = await this . deviceManager . showDevicePicker ( supportedPlatforms ) ;
274+
275+ // Refresh the supported platforms, as the we may have enabled new platforms during
276+ // the call to showDevicePicker.
277+ supportedPlatforms = this . daemon . capabilities . providesPlatformTypes && debugConfig . cwd
278+ ? ( await this . daemon . getSupportedPlatforms ( debugConfig . cwd ) ) . platforms
279+ : [ ] ;
280+
281+ // If we still don't have a valid device, show an error.
282+ if ( ! this . deviceManager . isSupported ( supportedPlatforms , deviceToLaunchOn ) ) {
283+ logger . warn ( "Unable to launch due to no active device" ) ;
284+ window . showInformationMessage ( "Cannot launch without an active device" ) ;
285+ return undefined ; // undefined means silent (don't open launch.json).
286+ }
274287 }
275288 }
276289
@@ -304,7 +317,7 @@ export class DebugConfigProvider implements DebugConfigurationProvider {
304317 const file = fsPath ( fd [ 0 ] ) ;
305318 return isWithinPath ( file , debugConfig . cwd )
306319 // Ignore errors in test folder unless it's the file we're running.
307- && ( ! isInsideFolderNamed ( file , "test" ) || file === debugConfig . program ) ;
320+ && ( ( ! isInsideFolderNamed ( file , "test" ) || ! isInsideFolderNamed ( file , "integration_test" ) ) || file === debugConfig . program ) ;
308321 } ) ;
309322 if ( firstRelevantDiagnostic ) {
310323 logger . warn ( "Project has errors, prompting user" ) ;
@@ -601,6 +614,15 @@ export class DynamicDebugConfigProvider implements DebugConfigurationProvider {
601614 type : "dart" ,
602615 } ) ;
603616 }
617+ if ( isFlutter && exists ( "integration_test" ) ) {
618+ results . push ( {
619+ name : `${ name } (${ isFlutter ? "Flutter" : "Dart" } Integration Tests)` ,
620+ program : "integration_test" ,
621+ cwd,
622+ request : "launch" ,
623+ type : "dart" ,
624+ } ) ;
625+ }
604626 }
605627 return results ;
606628 }
0 commit comments