Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 9 additions & 12 deletions Scripts/fastlane/ScreenshotFastfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,28 +38,25 @@ platform :ios do
derived_data_path: derived_data_path,
)

# By default, clear previous screenshots
should_clear_previous_screenshots = true
languages = "da de-DE en-AU en-CA en-GB en-US es-ES fr-FR id it ja ko no nl-NL pt-BR pt-PT ru sv th tr zh-Hans zh-Hant".split(" ")
languages = "da de-DE en-AU en-CA en-GB es-ES fr-FR id it ja ko no nl-NL pt-BR pt-PT ru sv th tr zh-Hans zh-Hant en-US".split(" ")

# Allow creating screenshots for just one languages
if options[:language] != nil
languages.keep_if { |language|
language.casecmp(options[:language]) == 0
}

# Don't clear, because we might just be fixing one locale
should_clear_previous_screenshots = false
end

puts languages

capture_ios_screenshots(
test_without_building: true,
derived_data_path: derived_data_path,
languages: languages,
clear_previous_screenshots: should_clear_previous_screenshots,
)
[true, false].each { | dark_mode_enabled |
capture_ios_screenshots(
test_without_building: true,
derived_data_path: derived_data_path,
languages: languages,
dark_mode: dark_mode_enabled
)
}
end

#####################################################################################
Expand Down
1 change: 0 additions & 1 deletion Scripts/fastlane/Snapfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ reinstall_app true
erase_simulator true
localize_simulator true
concurrent_simulators false
clear_previous_screenshots true

# By default, the latest version should be used automatically. If you want to change it, do it here
# ios_version '8.1'
Expand Down
70 changes: 32 additions & 38 deletions WordPress/WordPressScreenshotGeneration/SnapshotHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,13 @@ func snapshot(_ name: String, timeWaitingForIdle timeout: TimeInterval = 20) {
}

enum SnapshotError: Error, CustomDebugStringConvertible {
case cannotDetectUser
case cannotFindHomeDirectory
case cannotFindSimulatorHomeDirectory
case cannotAccessSimulatorHomeDirectory(String)
case cannotRunOnPhysicalDevice

var debugDescription: String {
switch self {
case .cannotDetectUser:
return "Couldn't find Snapshot configuration files - can't detect current user "
case .cannotFindHomeDirectory:
return "Couldn't find Snapshot configuration files - can't detect `Users` dir"
case .cannotFindSimulatorHomeDirectory:
return "Couldn't find simulator home location. Please, check SIMULATOR_HOST_HOME env variable."
case .cannotAccessSimulatorHomeDirectory(let simulatorHostHome):
return "Can't prepare environment. Simulator home location is inaccessible. Does \(simulatorHostHome) exist?"
case .cannotRunOnPhysicalDevice:
return "Can't use Snapshot on a physical device."
}
Expand All @@ -75,7 +66,7 @@ open class Snapshot: NSObject {
Snapshot.waitForAnimations = waitForAnimations

do {
let cacheDir = try pathPrefix()
let cacheDir = try getCacheDirectory()
Snapshot.cacheDirectory = cacheDir
setLanguage(app)
setLocale(app)
Expand Down Expand Up @@ -174,6 +165,8 @@ open class Snapshot: NSObject {
}

let screenshot = XCUIScreen.main.screenshot()
let image = XCUIDevice.shared.orientation.isLandscape ? fixLandscapeOrientation(image: screenshot.image) : screenshot.image

guard var simulator = ProcessInfo().environment["SIMULATOR_DEVICE_NAME"], let screenshotsDir = screenshotsDirectory else { return }

do {
Expand All @@ -183,14 +176,27 @@ open class Snapshot: NSObject {
simulator = regex.stringByReplacingMatches(in: simulator, range: range, withTemplate: "")

let path = screenshotsDir.appendingPathComponent("\(simulator)-\(name).png")
try screenshot.pngRepresentation.write(to: path)
try image.pngData()?.write(to: path, options: .atomic)
} catch let error {
NSLog("Problem writing screenshot: \(name) to \(screenshotsDir)/\(simulator)-\(name).png")
NSLog(error.localizedDescription)
}
#endif
}

class func fixLandscapeOrientation(image: UIImage) -> UIImage {
if #available(iOS 10.0, *) {
let format = UIGraphicsImageRendererFormat()
format.scale = image.scale
let renderer = UIGraphicsImageRenderer(size: image.size, format: format)
return renderer.image { context in
image.draw(in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
}
} else {
return image
}
}

class func waitForLoadingIndicatorToDisappear(within timeout: TimeInterval) {
#if os(tvOS)
return
Expand All @@ -206,51 +212,39 @@ open class Snapshot: NSObject {
_ = XCTWaiter.wait(for: [networkLoadingIndicatorDisappeared], timeout: timeout)
}

class func pathPrefix() throws -> URL? {
let homeDir: URL
class func getCacheDirectory() throws -> URL {
let cachePath = "Library/Caches/tools.fastlane"
// on OSX config is stored in /Users/<username>/Library
// and on iOS/tvOS/WatchOS it's in simulator's home dir
#if os(OSX)
guard let user = ProcessInfo().environment["USER"] else {
throw SnapshotError.cannotDetectUser
}

guard let usersDir = FileManager.default.urls(for: .userDirectory, in: .localDomainMask).first else {
throw SnapshotError.cannotFindHomeDirectory
let homeDir = URL(fileURLWithPath: NSHomeDirectory())
return homeDir.appendingPathComponent(cachePath)
#elseif arch(i386) || arch(x86_64)
guard let simulatorHostHome = ProcessInfo().environment["SIMULATOR_HOST_HOME"] else {
throw SnapshotError.cannotFindSimulatorHomeDirectory
}

homeDir = usersDir.appendingPathComponent(user)
let homeDir = URL(fileURLWithPath: simulatorHostHome)
return homeDir.appendingPathComponent(cachePath)
#else
#if arch(i386) || arch(x86_64)
guard let simulatorHostHome = ProcessInfo().environment["SIMULATOR_HOST_HOME"] else {
throw SnapshotError.cannotFindSimulatorHomeDirectory
}
guard let homeDirUrl = URL(string: simulatorHostHome) else {
throw SnapshotError.cannotAccessSimulatorHomeDirectory(simulatorHostHome)
}
homeDir = URL(fileURLWithPath: homeDirUrl.path)
#else
throw SnapshotError.cannotRunOnPhysicalDevice
#endif
throw SnapshotError.cannotRunOnPhysicalDevice
#endif
return homeDir.appendingPathComponent("Library/Caches/tools.fastlane")
}
}

private extension XCUIElementAttributes {
var isNetworkLoadingIndicator: Bool {
if hasWhiteListedIdentifier { return false }
if hasAllowListedIdentifier { return false }

let hasOldLoadingIndicatorSize = frame.size == CGSize(width: 10, height: 20)
let hasNewLoadingIndicatorSize = frame.size.width.isBetween(46, and: 47) && frame.size.height.isBetween(2, and: 3)

return hasOldLoadingIndicatorSize || hasNewLoadingIndicatorSize
}

var hasWhiteListedIdentifier: Bool {
let whiteListedIdentifiers = ["GeofenceLocationTrackingOn", "StandardLocationTrackingOn"]
var hasAllowListedIdentifier: Bool {
let allowListedIdentifiers = ["GeofenceLocationTrackingOn", "StandardLocationTrackingOn"]

return whiteListedIdentifiers.contains(identifier)
return allowListedIdentifiers.contains(identifier)
}

func isStatusBar(_ deviceWidth: CGFloat) -> Bool {
Expand Down Expand Up @@ -300,4 +294,4 @@ private extension CGFloat {

// Please don't remove the lines below
// They are used to detect outdated configuration files
// SnapshotHelperVersion [1.21]
// SnapshotHelperVersion [1.24]
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@ class WordPressScreenshotGeneration: XCTestCase {
let postEditorScreenshot = postList.selectPost(withSlug: "our-services")
sleep(imagesWaitTime) // wait for post images to load
if isIpad {
snapshot("1-Editor")
BlockEditorScreen()
.thenTakeScreenshot(1, named: "Editor")
} else {
BlockEditorScreen().openBlockPicker()
snapshot("1-Editor-With-BlockPicker")
BlockEditorScreen().closeBlockPicker()
BlockEditorScreen()
.openBlockPicker()
.thenTakeScreenshot(1, named: "Editor-With-BlockPicker")
.closeBlockPicker()
}
postEditorScreenshot.close()

Expand All @@ -62,9 +64,9 @@ class WordPressScreenshotGeneration: XCTestCase {
.gotoPostsScreen()
.showOnly(.drafts)
.selectPost(withSlug: "easy-blueberry-muffins")
BlockEditorScreen().selectBlock(containingText: "Ingredients")
BlockEditorScreen().selectBlock(containingText: "Ingredients")
sleep(imagesWaitTime) // wait for post images to load
snapshot("7-Editor-With-Keyboard")
BlockEditorScreen().thenTakeScreenshot(7, named: "Editor-With-Keyboard")
ipadScreenshot.close()
} else {
postList.pop()
Expand All @@ -74,12 +76,12 @@ class WordPressScreenshotGeneration: XCTestCase {
let mySite = MySiteScreen()
.showSiteSwitcher()
.switchToSite(withTitle: "tricountyrealestate.wordpress.com")
snapshot("4-MySite")
.thenTakeScreenshot(4, named: "MySite")

// Get Media screenshot
_ = mySite.gotoMediaScreen()
sleep(imagesWaitTime) // wait for post images to load
snapshot("6-Media")
mySite.thenTakeScreenshot(6, named: "Media")

if !isIpad {
postList.pop()
Expand All @@ -90,23 +92,36 @@ class WordPressScreenshotGeneration: XCTestCase {
statsScreen
.dismissCustomizeInsightsNotice()
.switchTo(mode: .months)
snapshot("3-Stats")
.thenTakeScreenshot(3, named: "Stats")

// Get Discover screenshot
// Currently, the view includes the "You Might Like" section
TabNavComponent()
.gotoReaderScreen()
.openDiscover()
snapshot("2-Discover")
.thenTakeScreenshot(2, named: "Discover")

// Get Notifications screenshot
let notificationList = TabNavComponent()
.gotoNotificationsScreen()
.dismissNotificationAlertIfNeeded()
if isIpad {
notificationList.openNotification(withText: "Reyansh Pawar commented on My Top 10 Pastry Recipes")
.replyToNotification()
notificationList
.openNotification(withText: "Reyansh Pawar commented on My Top 10 Pastry Recipes")
.replyToNotification()
}
snapshot("5-Notifications")
notificationList.thenTakeScreenshot(5, named: "Notifications")
}
}

extension BaseScreen {
@discardableResult
func thenTakeScreenshot(_ index: Int, named title: String) -> Self {
let mode = isDarkMode ? "dark" : "light"
let filename = "\(index)-\(mode)-\(title)"

snapshot(filename)

return self
}
}
4 changes: 3 additions & 1 deletion WordPress/WordPressUITests/Screens/ReaderScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ class ReaderScreen: BaseScreen {
return XCUIApplication().tables[ElementStringIDs.readerTable].exists
}

func openDiscover() {
func openDiscover() -> ReaderScreen {
discoverButton.tap()

return self
}
}
8 changes: 8 additions & 0 deletions WordPress/WordPressUITests/Utils/XCTest+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ var isIpad: Bool {
return UIDevice.current.userInterfaceIdiom == .pad
}

var isDarkMode: Bool {
if #available(iOS 12.0, *) {
return UIViewController().traitCollection.userInterfaceStyle == .dark
} else {
return false
}
}

let navBackButton = XCUIApplication().navigationBars.element(boundBy: 0).buttons.element(boundBy: 0)

extension XCUIElement {
Expand Down