screengrab 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: aa8ecf68f1116cde3b751b31625d15e8e6a45cae
4
+ data.tar.gz: 0aa647eb1a22a6cda026710956596c3ec724465f
5
+ SHA512:
6
+ metadata.gz: 396cf596e9eab3c794732b054ae6df6f974e1c3a254ee145681ee24fc335a3d99bbd5203be774f48e2fbfd708c43047bbdd26b71d1d16c47fef0e31772d550da
7
+ data.tar.gz: 230e1bba557341aa303a0adc39334067c8e74be1a21728e191087314209269873818152e3356699fd586d45301c17369d166eea053e3810e6d553ab99bfdf0bb
data/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Twitter, Inc
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ Chmod.java and Screengrab.java based on work Copyright (c) Square, Inc,
24
+ Used under permission of the Apache 2.0 License
25
+ http://www.apache.org/licenses/LICENSE-2.0
data/README.md ADDED
@@ -0,0 +1,178 @@
1
+ <h3 align="center">
2
+ <a href="https://github.com/fastlane/fastlane">
3
+ <img src="assets/fastlane.png" width="150" />
4
+ <br />
5
+ fastlane
6
+ </a>
7
+ </h3>
8
+ <p align="center">
9
+ <a href="https://github.com/fastlane/deliver">deliver</a> &bull;
10
+ <b>screengrab</b> &bull;
11
+ <a href="https://github.com/fastlane/frameit">frameit</a> &bull;
12
+ <a href="https://github.com/fastlane/pem">pem</a> &bull;
13
+ <a href="https://github.com/fastlane/sigh">sigh</a> &bull;
14
+ <a href="https://github.com/fastlane/produce">produce</a> &bull;
15
+ <a href="https://github.com/fastlane/cert">cert</a> &bull;
16
+ <a href="https://github.com/fastlane/spaceship">spaceship</a> &bull;
17
+ <a href="https://github.com/fastlane/pilot">pilot</a> &bull;
18
+ <a href="https://github.com/fastlane/boarding">boarding</a> &bull;
19
+ <a href="https://github.com/fastlane/gym">gym</a> &bull;
20
+ <a href="https://github.com/fastlane/scan">scan</a> &bull;
21
+ <a href="https://github.com/fastlane/match">match</a>
22
+ </p>
23
+ -------
24
+
25
+ <p align="center">
26
+ <img src="assets/screengrab.png" height="110">
27
+ </p>
28
+
29
+ screengrab
30
+ ============
31
+
32
+ [![Twitter: @FastlaneTools](https://img.shields.io/badge/contact-@FastlaneTools-blue.svg?style=flat)](https://twitter.com/FastlaneTools)
33
+ [![License](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://github.com/fastlane/screengrab/blob/master/LICENSE)
34
+ [![Gem](https://img.shields.io/gem/v/screengrab.svg?style=flat)](http://rubygems.org/gems/screengrab)
35
+
36
+ ### Automates screenshots of your Android app
37
+
38
+ Screengrab is a commandline tool that automates taking localized screenshots of your Android app.
39
+
40
+ <img src="assets/running-screengrab.gif" width="640">
41
+
42
+ ### Why should I automate this process?
43
+ - Create hundreds of screenshots in multiple languages on emulators or real devices, saving you hours
44
+ - Easily verify that localizations fit into labels on all screen dimensions to find UI mistakes before you ship
45
+ - You only need to configure it once for anyone on your team to run it
46
+ - Keep your screenshots perfectly up-to-date with every app update. Your customers deserve it!
47
+ - Fully integrates with [`fastlane`](https://fastlane.tools) and [`supply`](https://github.com/fastlane/supply)
48
+
49
+ # Installation
50
+
51
+ Once this tool is officially released, the installation will be as simple as running `gem install screengrab` For the private alpha, please follow these testing instructions:
52
+
53
+ ##### Command line tool installation
54
+ 1. Clone the repo with `git clone git@github.com:fastlane/screengrab.git`
55
+ 1. `cd` into your screengrab repo directory and run `rake install`
56
+ - You may need to `gem install bundler` if you don't already have bundler
57
+ - If you're using the default Ruby on Mac OS you may need to use `sudo`
58
+ 1. Run `screengrab init` to complete installation
59
+
60
+ ##### Gradle dependency
61
+ ```java
62
+ androidTestCompile 'tools.fastlane:screengrab:0.1.1'
63
+ ```
64
+
65
+ ##### Configuring your Manifest Permissions
66
+ Ensure that the following permissions exist in your **src/debug/AndroidManifest.xml**
67
+
68
+ ```xml
69
+ <!-- Allows unlocking your device and activating its screen so UI tests can succeed -->
70
+ <uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
71
+ <uses-permission android:name="android.permission.WAKE_LOCK"/>
72
+
73
+ <!-- Allows for storing and retrieving screenshots -->
74
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
75
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
76
+
77
+ <!-- Allows changing locales -->
78
+ <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
79
+ ```
80
+
81
+ ##### Configuring your <a href="#ui-tests">UI Tests</a> for Screenshots
82
+
83
+ 1. Add `@ClassRule public static final LocaleTestRule localeTestRule = new LocaleTestRule();` to your tests class to handle automatic switching of locales
84
+ 2. To capture screenshots, add the following to your tests `Screengrab.screenshot("name_of_screenshot_here");` on the appropriate screens
85
+
86
+ # Generating Screenshots with Screengrab
87
+ - Then, before running `screengrab` you'll need a debug and test apk
88
+ - You can create your APKs with `./gradlew assembleDebug assembleAndroidTest`
89
+ - Once complete run `screengrab` in your app project directory to generate screenshots
90
+ - You will be prompted to provide any required parameters which are not in your **Screengrabfile** or provided as command line arguments
91
+ - Your screenshots will be saved in a /screenshots directory in the directory where you ran `screengrab`
92
+
93
+ ## Advanced Screengrabfile Configuration
94
+
95
+ Running `screengrab init` generated a Screengrabfile which can store all of your configuration options. Since most values will not change often for your project, it is recommended to store them there.
96
+
97
+ The `Screengrabfile` is written in Ruby, so you may find it helpful to use an editor that highlights Ruby syntax to modify this file.
98
+
99
+ ```ruby
100
+ # remove the leading '#' to uncomment lines
101
+
102
+ # app_package_name 'your.app.package'
103
+ # use_tests_in_packages ['your.screenshot.tests.package']
104
+
105
+ # app_apk_path 'path/to/your/app.apk'
106
+ # tests_apk_path 'path/to/your/tests.apk'
107
+
108
+ locales ['en-US', 'fr-FR', 'it-IT']
109
+
110
+ # clear all previously generated screenshots in your local output directory before creating new ones
111
+ clear_previous_screenshots true
112
+ ```
113
+
114
+ For more information about all available options run
115
+
116
+ ```
117
+ screengrab --help
118
+ ```
119
+
120
+ # Tips
121
+
122
+ # UI Tests
123
+
124
+ Check out [Testing UI for a Single App](http://developer.android.com/training/testing/ui-testing/espresso-testing.html) for an introduction to using Espresso for UI testing.
125
+
126
+ ##### Example UI Test Class (Using JUnit4)
127
+ ```java
128
+ @RunWith(JUnit4.class)
129
+ public class JUnit4StyleTests {
130
+ @ClassRule
131
+ public static final LocaleTestRule localeTestRule = new LocaleTestRule();
132
+
133
+ @Rule
134
+ public ActivityTestRule<MainActivity> activityRule = new ActivityTestRule<>(MainActivity.class);
135
+
136
+ @Test
137
+ public void testTakeScreenshot() {
138
+ Screengrab.screenshot("before_button_click");
139
+
140
+ onView(withId(R.id.fab)).perform(click());
141
+
142
+ Screengrab.screenshot("after_button_click");
143
+ }
144
+ }
145
+
146
+ ```
147
+ There is an [example project](https://github.com/fastlane/screengrab/tree/master/example/src/androidTest/java/io/fabric/localetester) showing how to use use JUnit 3 or 4 and Espresso with the screengrab Java library to capture screenshots during a UI test run.
148
+
149
+ Using JUnit 4 is preferable because of its ability to perform actions before and after the entire test class is run. This means you will change the device's locale far fewer times when compared with JUnit 3 running those commands before and after each test method.
150
+
151
+ When using JUnit 3 you'll need to add a bit more code:
152
+
153
+ - Use `LocaleUtil.changeDeviceLocaleTo(LocaleUtil.getTestLocale());` in `setUp()`
154
+ - Use `LocaleUtil.changeDeviceLocaleTo(LocaleUtil.getEndingLocale());` in `tearDown()`
155
+ - Use `Screengrab.screenshot("name_of_screenshot_here");` to capture screenshots at the appropriate points in your tests
156
+
157
+ If you're having trouble getting your device unlocked and the screen activated to run tests, try using `ScreenUtil.activateScreenForTesting(activity);` in your test setup.
158
+
159
+ ## [`fastlane`](https://fastlane.tools) Toolchain
160
+
161
+ - [`fastlane`](https://fastlane.tools): Connect all deployment tools into one streamlined workflow
162
+ - [`supply`](https://github.com/fastlane/supply): Upload screenshots, metadata and your app to the Play Store
163
+
164
+ You can find all the tools on [fastlane.tools](https://fastlane.tools).
165
+
166
+ ##### [Like this tool? Be the first to know about updates and new fastlane tools](https://tinyletter.com/krausefx)
167
+
168
+ # Need help?
169
+ Please submit an issue on GitHub and provide information about your setup.
170
+
171
+ ## Code of Conduct
172
+
173
+ Help us keep `screengrab` open and inclusive. Please read and follow our [Code of Conduct](https://github.com/fastlane/code-of-conduct).
174
+
175
+ # License
176
+ This project is licensed under the terms of the MIT license. See the LICENSE file.
177
+
178
+ > This project is open source under the MIT license, which means you have full access to the source code and can modify it to fit your own needs. All fastlane tools run on your own computer or server, so your credentials or other sensitive information will never leave your own computer. You are responsible for how you use fastlane tools.
data/bin/screengrab ADDED
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.push File.expand_path("../../lib", __FILE__)
4
+
5
+ require 'screengrab'
6
+ require 'commander'
7
+
8
+ HighLine.track_eof = false
9
+
10
+ class ScreengrabApplication
11
+ include Commander::Methods
12
+
13
+ def run
14
+ program :version, Screengrab::VERSION
15
+ program :description, 'CLI for \'screengrab\' - Automate taking localized screenshots of your Android app on emulators or real devices'
16
+ program :help, 'Authors', 'Andrea Falcone <afalcone@twitter.com>, Michael Furtak <mfurtak@twitter.com>'
17
+ program :help, 'Website', 'https://fastlane.tools'
18
+ program :help, 'GitHub', 'https://github.com/fastlane/screengrab'
19
+ program :help_formatter, :compact
20
+
21
+ global_option('--verbose', 'Shows a more verbose output') { $verbose = true }
22
+
23
+ always_trace!
24
+
25
+ FastlaneCore::CommanderGenerator.new.generate(Screengrab::Options.available_options)
26
+
27
+ command :run do |c|
28
+ c.syntax = 'screengrab'
29
+ c.description = 'Take new screenshots based on the screengrabfile.'
30
+
31
+ c.action do |args, options|
32
+ o = options.__hash__.dup
33
+ o.delete(:verbose)
34
+ Screengrab.config = FastlaneCore::Configuration.create(Screengrab::Options.available_options, o)
35
+ Screengrab.android_environment = Screengrab::AndroidEnvironment.new(Screengrab.config[:android_home],
36
+ Screengrab.config[:build_tools_version])
37
+
38
+ Screengrab::DependencyChecker.check(Screengrab.android_environment)
39
+ Screengrab::Runner.new.run
40
+ end
41
+ end
42
+
43
+ command :init do |c|
44
+ c.syntax = 'screengrab init'
45
+ c.description = "Creates a new Screengrabfile in the current directory"
46
+
47
+ c.action do |args, options|
48
+ require 'screengrab/setup'
49
+ path = (Screengrab::Helper.fastlane_enabled? ? './fastlane' : '.')
50
+ Screengrab::Setup.create(path)
51
+ end
52
+ end
53
+
54
+ default_command :run
55
+
56
+ run!
57
+ end
58
+ end
59
+
60
+ begin
61
+ FastlaneCore::UpdateChecker.start_looking_for_update('screengrab')
62
+ ScreengrabApplication.new.run
63
+ ensure
64
+ FastlaneCore::UpdateChecker.show_update_status('screengrab', Screengrab::VERSION)
65
+ end
@@ -0,0 +1,15 @@
1
+ # remove the leading '#' to uncomment lines
2
+
3
+ # app_package_name 'your.app.package'
4
+ # use_tests_in_packages ['your.screenshot.tests.package']
5
+
6
+ # app_apk_path 'path/to/your/app.apk'
7
+ # tests_apk_path 'path/to/your/tests.apk'
8
+
9
+ locales ['en-US', 'fr-FR', 'it-IT']
10
+
11
+ # clear all previously generated screenshots in your local output directory before creating new ones
12
+ clear_previous_screenshots true
13
+
14
+ # For more information about all available options run
15
+ # screengrab --help
data/lib/screengrab.rb ADDED
@@ -0,0 +1,31 @@
1
+ require 'open3'
2
+ require 'fileutils'
3
+
4
+ require 'fastlane_core'
5
+
6
+ require 'screengrab/version'
7
+ require 'screengrab/runner'
8
+ require 'screengrab/detect_values'
9
+ require 'screengrab/dependency_checker'
10
+ require 'screengrab/options'
11
+ require 'screengrab/android_environment'
12
+
13
+ module Screengrab
14
+ # Use this to just setup the configuration attribute and set it later somewhere else
15
+ class << self
16
+ attr_accessor :config
17
+ attr_accessor :android_environment
18
+
19
+ def config=(value)
20
+ @config = value
21
+ DetectValues.set_additional_default_values
22
+ end
23
+
24
+ def screengrabfile_name
25
+ "Screengrabfile"
26
+ end
27
+ end
28
+
29
+ Helper = FastlaneCore::Helper # you gotta love Ruby: Helper.* should use the Helper class contained in FastlaneCore
30
+ UI = FastlaneCore::UI
31
+ end
@@ -0,0 +1,88 @@
1
+ module Screengrab
2
+ class AndroidEnvironment
3
+ attr_reader :android_home
4
+ attr_reader :build_tools_version
5
+
6
+ # android_home - the String path to the install location of the Android SDK
7
+ # build_tools_version - the String version of the Android build tools that should be used
8
+ def initialize(android_home, build_tools_version)
9
+ @android_home = android_home
10
+ @build_tools_version = build_tools_version
11
+ end
12
+
13
+ def platform_tools_path
14
+ @platform_tools_path ||= find_platform_tools(android_home)
15
+ end
16
+
17
+ def build_tools_path
18
+ @build_tools_path ||= find_build_tools(android_home, build_tools_version)
19
+ end
20
+
21
+ def adb_path
22
+ @adb_path ||= find_adb(platform_tools_path)
23
+ end
24
+
25
+ def aapt_path
26
+ @aapt_path ||= find_aapt(build_tools_path)
27
+ end
28
+
29
+ private
30
+
31
+ def find_platform_tools(android_home)
32
+ return nil unless android_home
33
+
34
+ platform_tools_path = File.join(android_home, 'platform-tools')
35
+ File.directory?(platform_tools_path) ? platform_tools_path : nil
36
+ end
37
+
38
+ def find_build_tools(android_home, build_tools_version)
39
+ return nil unless android_home
40
+
41
+ build_tools_dir = File.join(android_home, 'build-tools')
42
+
43
+ return nil unless build_tools_dir && File.directory?(build_tools_dir)
44
+
45
+ return File.join(build_tools_dir, build_tools_version) if build_tools_version
46
+
47
+ version = select_build_tools_version(build_tools_dir)
48
+
49
+ return version ? File.join(build_tools_dir, version) : nil
50
+ end
51
+
52
+ def select_build_tools_version(build_tools_dir)
53
+ # Collect the sub-directories of the build_tools_dir, rejecting any that start with '.' to remove . and ..
54
+ dir_names = Dir.entries(build_tools_dir).select { |e| !e.start_with?('.') && File.directory?(File.join(build_tools_dir, e)) }
55
+
56
+ # Collect a sorted array of Version objects from the directory names, handling the possibility that some
57
+ # entries may not be valid version names
58
+ versions = dir_names.map do |d|
59
+ begin
60
+ Gem::Version.new(d)
61
+ rescue
62
+ nil
63
+ end
64
+ end.reject(&:nil?).sort
65
+
66
+ # We'll take the last entry (highest version number) as the directory name we want
67
+ versions.last.to_s
68
+ end
69
+
70
+ def find_adb(platform_tools_path)
71
+ return FastlaneCore::CommandExecutor.which('adb') unless platform_tools_path
72
+
73
+ adb_path = File.join(platform_tools_path, 'adb')
74
+ return executable_command?(adb_path) ? adb_path : nil
75
+ end
76
+
77
+ def find_aapt(build_tools_path)
78
+ return FastlaneCore::CommandExecutor.which('aapt') unless build_tools_path
79
+
80
+ aapt_path = File.join(build_tools_path, 'aapt')
81
+ return executable_command?(aapt_path) ? aapt_path : nil
82
+ end
83
+
84
+ def executable_command?(cmd_path)
85
+ cmd_path && File.executable?(cmd_path) && !File.directory?(cmd_path)
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,56 @@
1
+ module Screengrab
2
+ class DependencyChecker
3
+ def self.check(android_env)
4
+ return if Helper.test?
5
+
6
+ check_adb(android_env)
7
+ check_aapt(android_env)
8
+ end
9
+
10
+ def self.check_adb(android_env)
11
+ android_home = android_env.android_home
12
+ adb_path = android_env.adb_path
13
+
14
+ warn_if_command_path_not_relative_to_android_home('adb', android_home, adb_path)
15
+ # adb is required to function, so we'll quit noisily if we couldn't find it
16
+ raise_missing_adb(android_home) unless adb_path
17
+ end
18
+
19
+ def self.raise_missing_adb(android_home)
20
+ if android_home
21
+ UI.error "The `adb` command could not be found relative to your provided ANDROID_HOME at #{android_home}"
22
+ UI.error "Please ensure that the Android SDK is installed and the platform-tools directory is present"
23
+ else
24
+ UI.error 'The `adb` command could not be found on your PATH'
25
+ UI.error 'Please ensure that the Android SDK is installed and the platform-tools directory is present and on your PATH'
26
+ end
27
+
28
+ UI.user_error! 'adb command not found'
29
+ end
30
+
31
+ def self.check_aapt(android_env)
32
+ android_home = android_env.android_home
33
+ aapt_path = android_env.aapt_path
34
+
35
+ warn_if_command_path_not_relative_to_android_home('aapt', android_home, aapt_path)
36
+ # aapt is not required in order to function, so we'll only warn if we can't find it.
37
+ warn_missing_aapt(android_home) unless aapt_path
38
+ end
39
+
40
+ def self.warn_missing_aapt(android_home)
41
+ if android_home
42
+ UI.important "The `aapt` command could not be found relative to your provided ANDROID_HOME at #{android_home}"
43
+ UI.important "Please ensure that the Android SDK is installed and you have the build tools downloaded"
44
+ else
45
+ UI.important "The `aapt` command could not be found on your PATH"
46
+ UI.important "Please ensure that the Android SDK is installed and you have the build tools downloaded and present on your PATH"
47
+ end
48
+ end
49
+
50
+ def self.warn_if_command_path_not_relative_to_android_home(cmd_name, android_home, cmd_path)
51
+ if android_home && cmd_path && !cmd_path.start_with?(android_home)
52
+ UI.important "Using `#{cmd_name}` found at #{cmd_path} which is not within the specified ANDROID_HOME at #{android_home}"
53
+ end
54
+ end
55
+ end
56
+ end