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
38a72a44
Commit
38a72a44
authored
Feb 20, 2016
by
Yegor
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2054 from yjbanov/flutter-drive-cmd
"flutter drive" command
parents
c113bea9
a2b1bd46
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
283 additions
and
23 deletions
+283
-23
driver.dart
packages/flutter_driver/lib/src/driver.dart
+40
-14
flutter_driver_test.dart
packages/flutter_driver/test/flutter_driver_test.dart
+1
-1
executable.dart
packages/flutter_tools/lib/executable.dart
+2
-0
file_system.dart
packages/flutter_tools/lib/src/base/file_system.dart
+27
-4
apk.dart
packages/flutter_tools/lib/src/commands/apk.dart
+1
-1
drive.dart
packages/flutter_tools/lib/src/commands/drive.dart
+103
-0
run.dart
packages/flutter_tools/lib/src/commands/run.dart
+2
-2
flx.dart
packages/flutter_tools/lib/src/flx.dart
+1
-1
pubspec.yaml
packages/flutter_tools/pubspec.yaml
+1
-0
drive_test.dart
packages/flutter_tools/test/drive_test.dart
+105
-0
No files found.
packages/flutter_driver/lib/src/driver.dart
View file @
38a72a44
...
...
@@ -12,25 +12,12 @@ import 'gesture.dart';
import
'health.dart'
;
import
'message.dart'
;
/// A function that connects to a Dart VM service given the [url].
typedef
Future
<
VMServiceClient
>
VMServiceConnectFunction
(
String
url
);
/// Connects to a real Dart VM service using the [VMServiceClient].
final
VMServiceConnectFunction
vmServiceClientConnectFunction
=
VMServiceClient
.
connect
;
/// The connection function used by [FlutterDriver.connect].
///
/// Overwrite this function if you require a different method for connecting to
/// the VM service.
VMServiceConnectFunction
vmServiceConnectFunction
=
vmServiceClientConnectFunction
;
final
Logger
_log
=
new
Logger
(
'FlutterDriver'
);
/// Drives a Flutter Application running in another process.
class
FlutterDriver
{
static
const
String
_flutterExtensionMethod
=
'ext.flutter_driver'
;
static
final
Logger
_log
=
new
Logger
(
'FlutterDriver'
);
/// Connects to a Flutter application.
///
...
...
@@ -174,3 +161,42 @@ class FlutterDriver {
return
null
;
});
}
/// A function that connects to a Dart VM service given the [url].
typedef
Future
<
VMServiceClient
>
VMServiceConnectFunction
(
String
url
);
/// The connection function used by [FlutterDriver.connect].
///
/// Overwrite this function if you require a custom method for connecting to
/// the VM service.
VMServiceConnectFunction
vmServiceConnectFunction
=
_waitAndConnect
;
/// Restores [vmServiceConnectFunction] to its default value.
void
restoreVmServiceConnectFunction
(
)
{
vmServiceConnectFunction
=
_waitAndConnect
;
}
/// Waits for a real Dart VM service to become available, then connects using
/// the [VMServiceClient].
///
/// Times out after 30 seconds.
Future
<
VMServiceClient
>
_waitAndConnect
(
String
url
)
async
{
Stopwatch
timer
=
new
Stopwatch
();
Future
<
VMServiceClient
>
attemptConnection
()
{
return
VMServiceClient
.
connect
(
url
)
.
catchError
((
e
)
async
{
if
(
timer
.
elapsed
<
const
Duration
(
seconds:
30
))
{
_log
.
info
(
'Waiting for application to start'
);
await
new
Future
.
delayed
(
const
Duration
(
seconds:
1
));
return
attemptConnection
();
}
else
{
_log
.
critical
(
'Application has not started in 30 seconds. '
'Giving up.'
);
throw
e
;
}
});
}
return
attemptConnection
();
}
packages/flutter_driver/test/flutter_driver_test.dart
View file @
38a72a44
...
...
@@ -40,7 +40,7 @@ main() {
tearDown
(()
async
{
await
logSub
.
cancel
();
vmServiceConnectFunction
=
vmServiceClientConnectFunction
;
restoreVmServiceConnectFunction
()
;
});
test
(
'connects to isolate paused at start'
,
()
async
{
...
...
packages/flutter_tools/lib/executable.dart
View file @
38a72a44
...
...
@@ -19,6 +19,7 @@ import 'src/commands/create.dart';
import
'src/commands/daemon.dart'
;
import
'src/commands/devices.dart'
;
import
'src/commands/doctor.dart'
;
import
'src/commands/drive.dart'
;
import
'src/commands/install.dart'
;
import
'src/commands/listen.dart'
;
import
'src/commands/logs.dart'
;
...
...
@@ -51,6 +52,7 @@ Future main(List<String> args) async {
..
addCommand
(
new
DaemonCommand
(
hideCommand:
!
verboseHelp
))
..
addCommand
(
new
DevicesCommand
())
..
addCommand
(
new
DoctorCommand
())
..
addCommand
(
new
DriveCommand
())
..
addCommand
(
new
InstallCommand
())
..
addCommand
(
new
ListenCommand
())
..
addCommand
(
new
LogsCommand
())
...
...
packages/flutter_tools/lib/src/base/file_system.dart
View file @
38a72a44
...
...
@@ -2,14 +2,37 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'
dart:io
'
;
import
'
package:file/io.dart
'
;
import
'package:file/sync_io.dart'
;
import
'package:path/path.dart'
as
path
;
export
'package:file/io.dart'
;
export
'package:file/sync_io.dart'
;
/// Currently active implmenetation of the file system.
///
/// By default it uses local disk-based implementation. Override this in tests
/// with [MemoryFileSystem].
FileSystem
fs
=
new
LocalFileSystem
();
SyncFileSystem
syncFs
=
new
SyncLocalFileSystem
();
/// Restores [fs] and [syncFs] to the default local disk-based implementation.
void
restoreFileSystem
(
)
{
fs
=
new
LocalFileSystem
();
syncFs
=
new
SyncLocalFileSystem
();
}
void
useInMemoryFileSystem
(
)
{
MemoryFileSystem
memFs
=
new
MemoryFileSystem
();
fs
=
memFs
;
syncFs
=
new
SyncMemoryFileSystem
(
backedBy:
memFs
.
storage
);
}
/// Create the ancestor directories of a file path if they do not already exist.
void
ensureDirectoryExists
(
String
filePath
)
{
String
dirPath
=
path
.
dirname
(
filePath
);
if
(
FileSystemEntity
.
isDirectorySync
(
dirPath
))
if
(
syncFs
.
type
(
dirPath
)
==
FileSystemEntityType
.
DIRECTORY
)
return
;
new
Directory
(
dirPath
).
createSync
(
recursive:
true
);
syncFs
.
directory
(
dirPath
).
create
(
recursive:
true
);
}
packages/flutter_tools/lib/src/commands/apk.dart
View file @
38a72a44
...
...
@@ -10,7 +10,7 @@ import 'package:path/path.dart' as path;
import
'../android/android_sdk.dart'
;
import
'../application_package.dart'
;
import
'../artifacts.dart'
;
import
'../base/file_system.dart'
;
import
'../base/file_system.dart'
show
ensureDirectoryExists
;
import
'../base/os.dart'
;
import
'../base/process.dart'
;
import
'../build_configuration.dart'
;
...
...
packages/flutter_tools/lib/src/commands/drive.dart
0 → 100644
View file @
38a72a44
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'package:path/path.dart'
as
path
;
import
'package:test/src/executable.dart'
as
executable
;
import
'../base/file_system.dart'
;
import
'../globals.dart'
;
import
'run.dart'
;
import
'stop.dart'
;
typedef
Future
<
int
>
RunAppFunction
();
typedef
Future
<
Null
>
RunTestsFunction
(
List
<
String
>
testArgs
);
typedef
Future
<
int
>
StopAppFunction
();
/// Runs integration (a.k.a. end-to-end) tests.
///
/// An integration test is a program that runs in a separate process from your
/// Flutter application. It connects to the application and acts like a user,
/// performing taps, scrolls, reading out widget properties and verifying their
/// correctness.
///
/// This command takes a target Flutter application that you would like to test
/// as the `--target` option (defaults to `lib/main.dart`). It then looks for a
/// file with the same name but containing the `_test.dart` suffix. The
/// `_test.dart` file is expected to be a program that uses
/// `package:flutter_driver` that exercises your application. Most commonly it
/// is a test written using `package:test`, but you are free to use something
/// else.
///
/// The app and the test are launched simultaneously. Once the test completes
/// the application is stopped and the command exits. If all these steps are
/// successful the exit code will be `0`. Otherwise, you will see a non-zero
/// exit code.
class
DriveCommand
extends
RunCommand
{
final
String
name
=
'drive'
;
final
String
description
=
'Runs Flutter Driver tests for the current project.'
;
final
List
<
String
>
aliases
=
<
String
>[
'driver'
];
RunAppFunction
_runApp
;
RunTestsFunction
_runTests
;
StopAppFunction
_stopApp
;
/// Creates a drive command with custom process management functions.
///
/// [runAppFn] starts a Flutter application.
///
/// [runTestsFn] runs tests.
///
/// [stopAppFn] stops the test app after tests are finished.
DriveCommand
.
custom
({
RunAppFunction
runAppFn
,
RunTestsFunction
runTestsFn
,
StopAppFunction
stopAppFn
})
{
_runApp
=
runAppFn
??
super
.
runInProject
;
_runTests
=
runTestsFn
??
executable
.
main
;
_stopApp
=
stopAppFn
??
this
.
stop
;
}
DriveCommand
()
:
this
.
custom
();
@override
Future
<
int
>
runInProject
()
async
{
String
testFile
=
_getTestFile
();
if
(
await
fs
.
type
(
testFile
)
!=
FileSystemEntityType
.
FILE
)
{
printError
(
'Test file not found:
$testFile
'
);
return
1
;
}
int
result
=
await
_runApp
();
if
(
result
!=
0
)
{
printError
(
'Application failed to start. Will not run test. Quitting.'
);
return
result
;
}
try
{
return
await
_runTests
([
testFile
])
.
then
((
_
)
=>
0
)
.
catchError
((
error
,
stackTrace
)
{
printError
(
'ERROR:
$error
\n
$stackTrace
'
);
return
1
;
});
}
finally
{
await
_stopApp
();
}
}
Future
<
int
>
stop
()
async
{
return
await
stopAll
(
devices
,
applicationPackages
)
?
0
:
2
;
}
String
_getTestFile
()
{
String
appFile
=
argResults
[
'target'
];
String
extension
=
path
.
extension
(
appFile
);
String
name
=
path
.
withoutExtension
(
appFile
);
return
'
${name}
_test
$extension
'
;
}
}
packages/flutter_tools/lib/src/commands/run.dart
View file @
38a72a44
...
...
@@ -164,12 +164,12 @@ Future<int> startApp(
if
(
stop
)
{
printTrace
(
'Running stop command.'
);
stopAll
(
devices
,
applicationPackages
);
await
stopAll
(
devices
,
applicationPackages
);
}
if
(
install
)
{
printTrace
(
'Running install command.'
);
installApp
(
devices
,
applicationPackages
);
await
installApp
(
devices
,
applicationPackages
);
}
bool
startedSomething
=
false
;
...
...
packages/flutter_tools/lib/src/flx.dart
View file @
38a72a44
...
...
@@ -13,7 +13,7 @@ import 'package:flx/signing.dart';
import
'package:path/path.dart'
as
path
;
import
'package:yaml/yaml.dart'
;
import
'base/file_system.dart'
;
import
'base/file_system.dart'
show
ensureDirectoryExists
;
import
'globals.dart'
;
import
'toolchain.dart'
;
...
...
packages/flutter_tools/pubspec.yaml
View file @
38a72a44
...
...
@@ -13,6 +13,7 @@ dependencies:
args
:
^0.13.2+1
crypto
:
^0.9.1
den_api
:
^0.1.0
file
:
^0.1.0
mustache4dart
:
^1.0.0
path
:
^1.3.0
pub_semver
:
^1.0.0
...
...
packages/flutter_tools/test/drive_test.dart
0 → 100644
View file @
38a72a44
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'package:file/file.dart'
;
import
'package:flutter_tools/src/commands/drive.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/globals.dart'
;
import
'package:test/test.dart'
;
import
'src/common.dart'
;
import
'src/context.dart'
;
import
'src/mocks.dart'
;
main
()
=>
defineTests
();
defineTests
()
{
group
(
'drive'
,
()
{
setUp
(()
{
useInMemoryFileSystem
();
});
tearDown
(()
{
restoreFileSystem
();
});
testUsingContext
(
'returns 1 when test file is not found'
,
()
{
DriveCommand
command
=
new
DriveCommand
();
applyMocksToCommand
(
command
);
List
<
String
>
args
=
[
'drive'
,
'--target=/some/app/test/e2e.dart'
,
];
return
createTestCommandRunner
(
command
).
run
(
args
).
then
((
int
code
)
{
expect
(
code
,
equals
(
1
));
BufferLogger
buffer
=
logger
;
expect
(
buffer
.
errorText
,
contains
(
'Test file not found: /some/app/test/e2e_test.dart'
));
});
});
testUsingContext
(
'returns 1 when app fails to run'
,
()
async
{
DriveCommand
command
=
new
DriveCommand
.
custom
(
runAppFn:
expectAsync
(()
{
return
new
Future
.
value
(
1
);
}));
applyMocksToCommand
(
command
);
String
testApp
=
'/some/app/test/e2e.dart'
;
String
testFile
=
'/some/app/test/e2e_test.dart'
;
MemoryFileSystem
memFs
=
fs
;
await
memFs
.
file
(
testApp
).
writeAsString
(
'main() {}'
);
await
memFs
.
file
(
testFile
).
writeAsString
(
'main() {}'
);
List
<
String
>
args
=
[
'drive'
,
'--target=
$testApp
'
,
];
return
createTestCommandRunner
(
command
).
run
(
args
).
then
((
int
code
)
{
expect
(
code
,
equals
(
1
));
BufferLogger
buffer
=
logger
;
expect
(
buffer
.
errorText
,
contains
(
'Application failed to start. Will not run test. Quitting.'
));
});
});
testUsingContext
(
'returns 0 when test ends successfully'
,
()
async
{
String
testApp
=
'/some/app/test/e2e.dart'
;
String
testFile
=
'/some/app/test/e2e_test.dart'
;
DriveCommand
command
=
new
DriveCommand
.
custom
(
runAppFn:
expectAsync
(()
{
return
new
Future
<
int
>.
value
(
0
);
}),
runTestsFn:
expectAsync
((
List
<
String
>
testArgs
)
{
expect
(
testArgs
,
[
testFile
]);
return
new
Future
<
Null
>.
value
();
}),
stopAppFn:
expectAsync
(()
{
return
new
Future
<
int
>.
value
(
0
);
})
);
applyMocksToCommand
(
command
);
MemoryFileSystem
memFs
=
fs
;
await
memFs
.
file
(
testApp
).
writeAsString
(
'main() {}'
);
await
memFs
.
file
(
testFile
).
writeAsString
(
'main() {}'
);
List
<
String
>
args
=
[
'drive'
,
'--target=
$testApp
'
,
];
return
createTestCommandRunner
(
command
).
run
(
args
).
then
((
int
code
)
{
expect
(
code
,
equals
(
0
));
BufferLogger
buffer
=
logger
;
expect
(
buffer
.
errorText
,
isEmpty
);
});
});
});
}
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