Skip to content

Commit

Permalink
Add some stubs for grey box testing, share some implementations
Browse files Browse the repository at this point in the history
  • Loading branch information
artyom-razinov committed Feb 7, 2019
1 parent 16efbe3 commit a6ceb38
Show file tree
Hide file tree
Showing 24 changed files with 355 additions and 203 deletions.
21 changes: 0 additions & 21 deletions Frameworks/Grey/GreyPageObjectDependenciesFactory.swift

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import MixboxUiTestsFoundation

public final class GreyPageObjectDependenciesFactory: PageObjectDependenciesFactory {
/*
These dependencies might be a good start:
interactionExecutionLogger
testFailureRecorder
ipcClient
snapshotsComparisonUtility
stepLogger
pollingConfiguration
elementFinder
*/

private let interactionPerformerFactory: InteractionPerformerFactory
private let interactionFactory: InteractionFactory
private let pollingConfiguration: PollingConfiguration

public init(
interactionPerformerFactory: InteractionPerformerFactory,
interactionFactory: InteractionFactory,
pollingConfiguration: PollingConfiguration)
{
self.interactionPerformerFactory = interactionPerformerFactory
self.interactionFactory = interactionFactory
self.pollingConfiguration = pollingConfiguration
}

public func pageObjectElementFactory() -> PageObjectElementFactory {
return GreyPageObjectElementFactory(
interactionPerformerFactory: interactionPerformerFactory,
interactionFactory: interactionFactory,
pollingConfiguration: pollingConfiguration
)
}
}
88 changes: 88 additions & 0 deletions Frameworks/Grey/PageObjects/GreyPageObjectElementActions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import MixboxUiTestsFoundation

// TODO:
//
// 1. Share most of the code with XcuiPageObjectElementActions.
// 2. Remove XcuiPageObjectElementActions and GreyPageObjectElementActions, use shared class.
// (like GreyPageObjectElemenChecks and GreyPageObjectElemenActions became AlmightyElementChecksImpl)
//
public final class GreyPageObjectElementActions: AlmightyElementActions {
private let elementSettings: ElementSettings

public init(
elementSettings: ElementSettings)
{
self.elementSettings = elementSettings
}

public func tap(
normalizedCoordinate: CGPoint?,
absoluteOffset: CGVector?,
actionSettings: ActionSettings)
{
preconditionFailure("Not implemented")
}

public func press(
duration: Double,
normalizedCoordinate: CGPoint?,
absoluteOffset: CGVector?,
actionSettings: ActionSettings)
{
preconditionFailure("Not implemented")
}

public func setText(
text: String,
normalizedCoordinate: CGPoint?,
absoluteOffset: CGVector?,
actionSettings: ActionSettings)
{
preconditionFailure("Not implemented")
}

public func swipe(
direction: SwipeDirection,
actionSettings: ActionSettings)
{
preconditionFailure("Not implemented")
}

public func with(settings: ElementSettings) -> AlmightyElementActions {
preconditionFailure("Not implemented")
}

public func typeText(
text: String,
normalizedCoordinate: CGPoint?,
absoluteOffset: CGVector?,
actionSettings: ActionSettings)
{
preconditionFailure("Not implemented")
}

public func pasteText(
text: String,
normalizedCoordinate: CGPoint?,
absoluteOffset: CGVector?,
actionSettings: ActionSettings)
{
preconditionFailure("Not implemented")
}

public func cutText(
normalizedCoordinate: CGPoint?,
absoluteOffset: CGVector?,
actionSettings: ActionSettings)
{
preconditionFailure("Not implemented")
}

public func clearTextByTypingBackspaceMultipleTimes(
normalizedCoordinate: CGPoint?,
absoluteOffset: CGVector?,
actionSettings: ActionSettings)
{
preconditionFailure("Not implemented")
}
}
49 changes: 49 additions & 0 deletions Frameworks/Grey/PageObjects/GreyPageObjectElementFactory.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import MixboxUiTestsFoundation

public final class GreyPageObjectElementFactory: PageObjectElementFactory {
private let interactionPerformerFactory: InteractionPerformerFactory
private let interactionFactory: InteractionFactory
private let pollingConfiguration: PollingConfiguration

public init(
interactionPerformerFactory: InteractionPerformerFactory,
interactionFactory: InteractionFactory,
pollingConfiguration: PollingConfiguration)
{
self.interactionPerformerFactory = interactionPerformerFactory
self.interactionFactory = interactionFactory
self.pollingConfiguration = pollingConfiguration
}

public func pageObjectElement(
settings: ElementSettings)
-> AlmightyElement
{
let actions = GreyPageObjectElementActions(
elementSettings: settings
)

let checks = AlmightyElementChecksImpl(
elementSettings: settings,
interactionPerformerFactory: interactionPerformerFactory,
interactionFactory: interactionFactory,
isAssertions: false,
pollingConfiguration: pollingConfiguration
)

let asserts = AlmightyElementChecksImpl(
elementSettings: settings,
interactionPerformerFactory: interactionPerformerFactory,
interactionFactory: interactionFactory,
isAssertions: true,
pollingConfiguration: pollingConfiguration
)

return AlmightyElementImpl(
settings: settings,
actions: actions,
checks: checks,
asserts: asserts
)
}
}
13 changes: 13 additions & 0 deletions Frameworks/TestsFoundation/Utilities/Optional+UnwrapOrFail.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
extension Optional {
public func unwrapOrFail(file: StaticString = #file, line: UInt = #line) -> Wrapped {
guard let unwrapped = self else {
UnavoidableFailure.fail(
"Failed to unwrap \(type(of: self)), value is nil, which is not expected",
file: file,
line: line
)
}

return unwrapped
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
public protocol ElementResolver {
func resolveElement() -> ResolvedElementQuery
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
import MixboxUiTestsFoundation

protocol ElementResolver {
func resolveElement() -> ResolvedElementQuery
}

final class ElementResolverImpl: ElementResolver {
public final class ElementResolverImpl: ElementResolver {
private let elementFinder: ElementFinder
private let elementSettings: ElementSettings

init(
public init(
elementFinder: ElementFinder,
elementSettings: ElementSettings)
{
self.elementFinder = elementFinder
self.elementSettings = elementSettings
}

func resolveElement() -> ResolvedElementQuery {
public func resolveElement() -> ResolvedElementQuery {
let elementQuery = elementFinder.query(
elementMatcher: elementSettings.matcher && IsNotDefinitelyHiddenMatcher(),
waitForExistence: false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import XCTest
import MixboxTestsFoundation

// TODO: Make `minimalPercentageOfVisibleArea` customizable (from tests/from page object definitions).
// Now it depends only on the type of a check (it is hardcoded per each check). For example
// it is 100% for snapshot assertion, because we need all view to be visible.
public protocol InteractionFactory {
func actionInteraction(
specificImplementation: InteractionSpecificImplementation,
settings: ResolvedInteractionSettings,
minimalPercentageOfVisibleArea: CGFloat)
-> Interaction

func checkForNotDisplayedInteraction(
settings: ResolvedInteractionSettings,
minimalPercentageOfVisibleArea: CGFloat)
-> Interaction

func checkInteraction(
specificImplementation: InteractionSpecificImplementation,
settings: ResolvedInteractionSettings,
minimalPercentageOfVisibleArea: CGFloat)
-> Interaction
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
public protocol InteractionPerformerFactory {
func performerForInteraction(
shouldReportResultToObserver: Bool)
-> InteractionPerformer
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,19 @@
import MixboxUiTestsFoundation
import MixboxTestsFoundation
import MixboxReporting

protocol InteractionPerformerFactory {
func performerForInteraction(
shouldReportResultToObserver: Bool)
-> InteractionPerformer
}

final class InteractionPerformerFactoryImpl: InteractionPerformerFactory {
public final class InteractionPerformerFactoryImpl: InteractionPerformerFactory {
private let interactionExecutionLogger: InteractionExecutionLogger
private let testFailureRecorder: TestFailureRecorder

init(
public init(
interactionExecutionLogger: InteractionExecutionLogger,
testFailureRecorder: TestFailureRecorder)
{
self.interactionExecutionLogger = interactionExecutionLogger
self.testFailureRecorder = testFailureRecorder
}

func performerForInteraction(
public func performerForInteraction(
shouldReportResultToObserver: Bool)
-> InteractionPerformer
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import MixboxUiTestsFoundation

// `Interaction` is a generic interaction with an element.
// All specific lies inside `InteractionSpecificImplementation` which is stored by `Interaction`.
// E.g. every interaction needs to find an element. Only interaction for tapping needs to tap an element.
final class InteractionSpecificImplementation {
typealias ExecuteFunction = (_ snapshot: ElementSnapshot) -> InteractionSpecificResult
public final class InteractionSpecificImplementation {
public typealias ExecuteFunction = (_ snapshot: ElementSnapshot) -> InteractionSpecificResult
private let execute: ExecuteFunction

init(execute: @escaping ExecuteFunction) {
public init(execute: @escaping ExecuteFunction) {
self.execute = execute
}

func perform(snapshot: ElementSnapshot) -> InteractionSpecificResult {
public func perform(snapshot: ElementSnapshot) -> InteractionSpecificResult {
return execute(snapshot)
}
}

0 comments on commit a6ceb38

Please sign in to comment.