Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
5ee41472
Unverified
Commit
5ee41472
authored
Feb 23, 2020
by
Angjie Li
Committed by
GitHub
Feb 23, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow developers to run flutter driver web test directly (#51084)
parent
3f9d08a0
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
115 additions
and
34 deletions
+115
-34
devfs_web.dart
packages/flutter_tools/lib/src/build_runner/devfs_web.dart
+4
-2
resident_web_runner.dart
...utter_tools/lib/src/build_runner/resident_web_runner.dart
+15
-3
drive.dart
packages/flutter_tools/lib/src/commands/drive.dart
+61
-10
resident_runner.dart
packages/flutter_tools/lib/src/resident_runner.dart
+7
-0
web_device.dart
packages/flutter_tools/lib/src/web/web_device.dart
+15
-13
drive_test.dart
...lutter_tools/test/commands.shard/hermetic/drive_test.dart
+4
-4
hot_test.dart
packages/flutter_tools/test/general.shard/hot_test.dart
+6
-2
resident_web_runner_test.dart
...er_tools/test/general.shard/resident_web_runner_test.dart
+3
-0
No files found.
packages/flutter_tools/lib/src/build_runner/devfs_web.dart
View file @
5ee41472
...
...
@@ -438,7 +438,8 @@ class WebDevFS implements DevFS {
Set
<
String
>
get
assetPathsToEvict
=>
const
<
String
>{};
@override
Uri
get
baseUri
=>
null
;
Uri
get
baseUri
=>
_baseUri
;
Uri
_baseUri
;
@override
Future
<
Uri
>
create
()
async
{
...
...
@@ -451,7 +452,8 @@ class WebDevFS implements DevFS {
entrypoint
,
testMode:
testMode
,
);
return
Uri
.
parse
(
'http://
$hostname
:
$port
'
);
_baseUri
=
Uri
.
parse
(
'http://
$hostname
:
$port
'
);
return
_baseUri
;
}
@override
...
...
packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart
View file @
5ee41472
...
...
@@ -71,7 +71,7 @@ const String kExitMessage = 'Failed to establish connection with the applicatio
/// A hot-runner which handles browser specific delegation.
abstract
class
ResidentWebRunner
extends
ResidentRunner
{
ResidentWebRunner
(
this
.
device
,
{
FlutterDevice
device
,
{
String
target
,
@required
this
.
flutterProject
,
@required
bool
ipv6
,
...
...
@@ -79,14 +79,14 @@ abstract class ResidentWebRunner extends ResidentRunner {
bool
stayResident
=
true
,
@required
this
.
dartDefines
,
})
:
super
(
<
FlutterDevice
>[],
<
FlutterDevice
>[
device
],
target:
target
??
globals
.
fs
.
path
.
join
(
'lib'
,
'main.dart'
),
debuggingOptions:
debuggingOptions
,
ipv6:
ipv6
,
stayResident:
stayResident
,
);
final
FlutterDevice
device
;
FlutterDevice
get
device
=>
flutterDevices
.
first
;
final
FlutterProject
flutterProject
;
final
List
<
String
>
dartDefines
;
DateTime
firstBuildTime
;
...
...
@@ -249,6 +249,12 @@ abstract class ResidentWebRunner extends ResidentRunner {
}
}
@override
Future
<
void
>
stopEchoingDeviceLog
()
async
{
// Do nothing for ResidentWebRunner
await
device
.
stopEchoingDeviceLog
();
}
@override
Future
<
void
>
debugDumpSemanticsTreeInInverseHitTestOrder
()
async
{
try
{
...
...
@@ -705,4 +711,10 @@ class _ResidentWebRunner extends ResidentWebRunner {
await
cleanupAtFinish
();
return
0
;
}
@override
Future
<
void
>
exitApp
()
async
{
await
device
.
exitApps
();
appFinished
();
}
}
packages/flutter_tools/lib/src/commands/drive.dart
View file @
5ee41472
...
...
@@ -22,6 +22,7 @@ import '../globals.dart' as globals;
import
'../project.dart'
;
import
'../resident_runner.dart'
;
import
'../runner/flutter_command.dart'
show
FlutterCommandResult
;
import
'../web/web_runner.dart'
;
import
'run.dart'
;
/// Runs integration (a.k.a. end-to-end) tests.
...
...
@@ -142,17 +143,11 @@ class DriveCommand extends RunCommandBase {
}
String
observatoryUri
;
ResidentRunner
residentRunner
;
final
bool
isWebPlatform
=
await
device
.
targetPlatform
==
TargetPlatform
.
web_javascript
;
if
(
argResults
[
'use-existing-app'
]
==
null
)
{
globals
.
printStatus
(
'Starting application:
$targetFile
'
);
if
(
isWebPlatform
)
{
throwToolExit
(
'Flutter Driver (web) does not support running without use-existing-app.
\n
'
'Please launch your application beforehand and connects via use-existing-app.'
);
}
if
(
getBuildInfo
().
isRelease
&&
!
isWebPlatform
)
{
// This is because we need VM service to be able to drive the app.
// For Flutter Web, testing in release mode is allowed.
...
...
@@ -164,7 +159,53 @@ class DriveCommand extends RunCommandBase {
);
}
final
LaunchResult
result
=
await
appStarter
(
this
);
if
(
isWebPlatform
&&
getBuildInfo
().
isDebug
)
{
// TODO(angjieli): remove this once running against
// target under test_driver in debug mode is supported
throwToolExit
(
'Flutter Driver web does not support running in debug mode.
\n
'
'
\n
'
'Use --profile mode for testing application performance.
\n
'
'Use --release mode for testing correctness (with assertions).'
);
}
Uri
webUri
;
if
(
isWebPlatform
)
{
// Start Flutter web application for current test
final
FlutterProject
flutterProject
=
FlutterProject
.
current
();
final
FlutterDevice
flutterDevice
=
await
FlutterDevice
.
create
(
device
,
flutterProject:
flutterProject
,
trackWidgetCreation:
boolArg
(
'track-widget-creation'
),
target:
targetFile
,
buildMode:
getBuildMode
()
);
residentRunner
=
webRunnerFactory
.
createWebRunner
(
flutterDevice
,
target:
targetFile
,
flutterProject:
flutterProject
,
ipv6:
ipv6
,
debuggingOptions:
DebuggingOptions
.
enabled
(
getBuildInfo
()),
stayResident:
false
,
dartDefines:
dartDefines
,
urlTunneller:
null
,
);
final
Completer
<
void
>
appStartedCompleter
=
Completer
<
void
>.
sync
();
final
int
result
=
await
residentRunner
.
run
(
appStartedCompleter:
appStartedCompleter
,
route:
route
,
);
if
(
result
!=
0
)
{
throwToolExit
(
null
,
exitCode:
result
);
}
// Wait until the app is started.
await
appStartedCompleter
.
future
;
webUri
=
residentRunner
.
uri
;
}
final
LaunchResult
result
=
await
appStarter
(
this
,
webUri
);
if
(
result
==
null
)
{
throwToolExit
(
'Application failed to start. Will not run test. Quitting.'
,
exitCode:
1
);
}
...
...
@@ -243,6 +284,7 @@ $ex
}
throw
Exception
(
'Unable to run test:
$error
\n
$stackTrace
'
);
}
finally
{
await
residentRunner
?.
exit
();
await
driver
?.
quit
();
if
(
boolArg
(
'keep-app-running'
)
??
(
argResults
[
'use-existing-app'
]
!=
null
))
{
globals
.
printStatus
(
'Leaving the application running.'
);
...
...
@@ -327,14 +369,14 @@ Future<Device> findTargetDevice() async {
}
/// Starts the application on the device given command configuration.
typedef
AppStarter
=
Future
<
LaunchResult
>
Function
(
DriveCommand
command
);
typedef
AppStarter
=
Future
<
LaunchResult
>
Function
(
DriveCommand
command
,
Uri
webUri
);
AppStarter
appStarter
=
_startApp
;
// (mutable for testing)
void
restoreAppStarter
(
)
{
appStarter
=
_startApp
;
}
Future
<
LaunchResult
>
_startApp
(
DriveCommand
command
)
async
{
Future
<
LaunchResult
>
_startApp
(
DriveCommand
command
,
Uri
webUri
)
async
{
final
String
mainPath
=
findMainDartFile
(
command
.
targetFile
);
if
(
await
globals
.
fs
.
type
(
mainPath
)
!=
FileSystemEntityType
.
file
)
{
globals
.
printError
(
'Tried to run
$mainPath
, but that file does not exist.'
);
...
...
@@ -360,6 +402,15 @@ Future<LaunchResult> _startApp(DriveCommand command) async {
platformArgs
[
'trace-startup'
]
=
command
.
traceStartup
;
}
if
(
webUri
!=
null
)
{
platformArgs
[
'uri'
]
=
webUri
.
toString
();
if
(!
command
.
getBuildInfo
().
isDebug
)
{
// For web device, startApp will be triggered twice
// and it will error out for chrome the second time.
platformArgs
[
'no-launch-chrome'
]
=
true
;
}
}
globals
.
printTrace
(
'Starting application.'
);
// Forward device log messages to the terminal window running the "drive" command.
...
...
packages/flutter_tools/lib/src/resident_runner.dart
View file @
5ee41472
...
...
@@ -680,6 +680,13 @@ abstract class ResidentRunner {
bool
get
isRunningRelease
=>
debuggingOptions
.
buildInfo
.
isRelease
;
bool
get
supportsServiceProtocol
=>
isRunningDebug
||
isRunningProfile
;
// Returns the Uri of the first connected device for mobile,
// and only connected device for web.
//
// Would be null if there is no device connected or
// there is no devFS associated with the first device.
Uri
get
uri
=>
flutterDevices
.
first
?.
devFS
?.
baseUri
;
/// Returns [true] if the resident runner exited after invoking [exit()].
bool
get
exited
=>
_exited
;
...
...
packages/flutter_tools/lib/src/web/web_device.dart
View file @
5ee41472
...
...
@@ -134,6 +134,8 @@ class ChromeDevice extends Device {
// See [ResidentWebRunner.run] in flutter_tools/lib/src/resident_web_runner.dart
// for the web initialization and server logic.
final
String
url
=
platformArgs
[
'uri'
]
as
String
;
final
bool
launchChrome
=
platformArgs
[
'no-launch-chrome'
]
!=
true
;
if
(
launchChrome
)
{
_chrome
=
await
chromeLauncher
.
launch
(
url
,
dataDir:
globals
.
fs
.
currentDirectory
...
...
@@ -142,10 +144,10 @@ class ChromeDevice extends Device {
headless:
debuggingOptions
.
webRunHeadless
,
debugPort:
debuggingOptions
.
webBrowserDebugPort
,
);
}
globals
.
logger
.
sendEvent
(
'app.webLaunchUrl'
,
<
String
,
dynamic
>{
'url'
:
url
,
'launched'
:
true
});
return
LaunchResult
.
succeeded
(
observatoryUri:
null
);
globals
.
logger
.
sendEvent
(
'app.webLaunchUrl'
,
<
String
,
dynamic
>{
'url'
:
url
,
'launched'
:
launchChrome
});
return
LaunchResult
.
succeeded
(
observatoryUri:
url
!=
null
?
Uri
.
parse
(
url
):
null
);
}
@override
...
...
@@ -268,7 +270,7 @@ class WebServerDevice extends Device {
globals
.
printStatus
(
'
$mainPath
is being served at
$url
'
,
emphasis:
true
);
}
globals
.
logger
.
sendEvent
(
'app.webLaunchUrl'
,
<
String
,
dynamic
>{
'url'
:
url
,
'launched'
:
false
});
return
LaunchResult
.
succeeded
(
observatoryUri:
null
);
return
LaunchResult
.
succeeded
(
observatoryUri:
url
!=
null
?
Uri
.
parse
(
url
):
null
);
}
@override
...
...
packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart
View file @
5ee41472
...
...
@@ -45,7 +45,7 @@ void main() {
fs
.
file
(
'pubspec.yaml'
)..
createSync
();
fs
.
file
(
'.packages'
).
createSync
();
setExitFunctionForTests
();
appStarter
=
(
DriveCommand
command
)
{
appStarter
=
(
DriveCommand
command
,
Uri
webUri
)
{
throw
'Unexpected call to appStarter'
;
};
testRunner
=
(
List
<
String
>
testArgs
,
Map
<
String
,
String
>
environment
)
{
...
...
@@ -91,7 +91,7 @@ void main() {
testUsingContext
(
'returns 1 when app fails to run'
,
()
async
{
testDeviceManager
.
addDevice
(
MockDevice
());
appStarter
=
expectAsync
1
((
DriveCommand
command
)
async
=>
null
);
appStarter
=
expectAsync
2
((
DriveCommand
command
,
Uri
webUri
)
async
=>
null
);
final
String
testApp
=
globals
.
fs
.
path
.
join
(
tempDir
.
path
,
'test_driver'
,
'e2e.dart'
);
final
String
testFile
=
globals
.
fs
.
path
.
join
(
tempDir
.
path
,
'test_driver'
,
'e2e_test.dart'
);
...
...
@@ -170,7 +170,7 @@ void main() {
final
String
testApp
=
globals
.
fs
.
path
.
join
(
tempDir
.
path
,
'test'
,
'e2e.dart'
);
final
String
testFile
=
globals
.
fs
.
path
.
join
(
tempDir
.
path
,
'test_driver'
,
'e2e_test.dart'
);
appStarter
=
expectAsync
1
((
DriveCommand
command
)
async
{
appStarter
=
expectAsync
2
((
DriveCommand
command
,
Uri
webUri
)
async
{
return
LaunchResult
.
succeeded
();
});
testRunner
=
expectAsync2
((
List
<
String
>
testArgs
,
Map
<
String
,
String
>
environment
)
async
{
...
...
@@ -207,7 +207,7 @@ void main() {
final
String
testApp
=
globals
.
fs
.
path
.
join
(
tempDir
.
path
,
'test'
,
'e2e.dart'
);
final
String
testFile
=
globals
.
fs
.
path
.
join
(
tempDir
.
path
,
'test_driver'
,
'e2e_test.dart'
);
appStarter
=
expectAsync
1
((
DriveCommand
command
)
async
{
appStarter
=
expectAsync
2
((
DriveCommand
command
,
Uri
webUri
)
async
{
return
LaunchResult
.
succeeded
();
});
testRunner
=
(
List
<
String
>
testArgs
,
Map
<
String
,
String
>
environment
)
async
{
...
...
packages/flutter_tools/test/general.shard/hot_test.dart
View file @
5ee41472
...
...
@@ -181,8 +181,10 @@ void main() {
FlutterDevice
(
mockDevice
,
generator:
residentCompiler
,
trackWidgetCreation:
false
,
buildMode:
BuildMode
.
debug
)..
devFS
=
mockDevFs
,
FlutterDevice
(
mockHotDevice
,
generator:
residentCompiler
,
trackWidgetCreation:
false
,
buildMode:
BuildMode
.
debug
)..
devFS
=
mockDevFs
,
];
final
OperationResult
result
=
await
HotRunner
(
devices
).
restart
(
fullRestart:
true
);
final
HotRunner
hotRunner
=
HotRunner
(
devices
);
final
OperationResult
result
=
await
hotRunner
.
restart
(
fullRestart:
true
);
// Expect hot restart was successful.
expect
(
hotRunner
.
uri
,
mockDevFs
.
baseUri
);
expect
(
result
.
isOk
,
true
);
expect
(
result
.
message
,
isNot
(
'hotRestart not supported'
));
},
overrides:
<
Type
,
Generator
>{
...
...
@@ -216,8 +218,10 @@ void main() {
final
List
<
FlutterDevice
>
devices
=
<
FlutterDevice
>[
FlutterDevice
(
mockDevice
,
generator:
residentCompiler
,
trackWidgetCreation:
false
,
buildMode:
BuildMode
.
debug
)..
devFS
=
mockDevFs
,
];
final
OperationResult
result
=
await
HotRunner
(
devices
).
restart
(
fullRestart:
true
);
final
HotRunner
hotRunner
=
HotRunner
(
devices
);
final
OperationResult
result
=
await
hotRunner
.
restart
(
fullRestart:
true
);
// Expect hot restart successful.
expect
(
hotRunner
.
uri
,
mockDevFs
.
baseUri
);
expect
(
result
.
isOk
,
true
);
expect
(
result
.
message
,
isNot
(
'setupHotRestart failed'
));
},
overrides:
<
Type
,
Generator
>{
...
...
packages/flutter_tools/test/general.shard/resident_web_runner_test.dart
View file @
5ee41472
...
...
@@ -119,6 +119,7 @@ void main() {
when
(
mockDebugConnection
.
uri
).
thenReturn
(
'ws://127.0.0.1/abcd/'
);
when
(
mockFlutterDevice
.
devFS
).
thenReturn
(
mockWebDevFS
);
when
(
mockWebDevFS
.
sources
).
thenReturn
(<
Uri
>[]);
when
(
mockWebDevFS
.
baseUri
).
thenReturn
(
Uri
.
parse
(
'http://localhost:12345'
));
when
(
mockFlutterDevice
.
generator
).
thenReturn
(
mockResidentCompiler
);
when
(
mockChrome
.
chromeConnection
).
thenReturn
(
mockChromeConnection
);
when
(
mockChromeConnection
.
getTab
(
any
)).
thenAnswer
((
Invocation
invocation
)
async
{
...
...
@@ -149,6 +150,7 @@ void main() {
}));
test
(
'runner with web server device supports debugging with --start-paused'
,
()
=>
testbed
.
run
(()
{
_setupMocks
();
when
(
mockFlutterDevice
.
device
).
thenReturn
(
WebServerDevice
());
final
ResidentRunner
profileResidentWebRunner
=
DwdsWebRunnerFactory
().
createWebRunner
(
mockFlutterDevice
,
...
...
@@ -160,6 +162,7 @@ void main() {
urlTunneller:
null
,
);
expect
(
profileResidentWebRunner
.
uri
,
mockWebDevFS
.
baseUri
);
expect
(
profileResidentWebRunner
.
debuggingEnabled
,
true
);
}));
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment