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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
51 changes: 29 additions & 22 deletions .github/workflows/swift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,73 +10,80 @@ defaults:
working-directory: Example
jobs:
lint:
runs-on: macos-15
runs-on: macos-26
steps:
- uses: actions/checkout@v4
- run: brew install swiftlint
- run: swiftlint lint
BuildSwiftPackage:
runs-on: macos-15
runs-on: macos-26
steps:
- uses: actions/checkout@v4
- run: sudo xcode-select -s /Applications/Xcode_16.3.app
- run: sudo xcode-select -s /Applications/Xcode_26.4.1.app
- name: Building Swift Package
run: xcodebuild clean build -scheme SPMBuild -workspace ConsentViewController.xcworkspace -destination 'platform=iOS Simulator,name=iPhone 16,OS=18.4'
run: xcodebuild clean build -scheme SPMBuild -workspace ConsentViewController.xcworkspace -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.4.1'
- uses: actions/upload-artifact@v4
if: failure()
name: Upload Swift Package build results
with:
path: /Users/runner/Library/Developer/Xcode/DerivedData/**/*.xcresult
BuildCarthageProject:
runs-on: macos-15
runs-on: macos-26
steps:
- uses: actions/checkout@v4
- run: sudo xcode-select -s /Applications/Xcode_16.3.app
- run: sudo xcode-select -s /Applications/Xcode_26.4.1.app
- name: Building Carthage Project
run: cd ./SPCarthageTest && ./build.sh
ObjC-ExampleApp-tests:
runs-on: macos-15
runs-on: macos-26
env:
TOOLCHAINS: com.apple.dt.toolchain.XcodeDefault
steps:
- uses: actions/checkout@v4
- run: sudo xcode-select -s /Applications/Xcode_16.3.app
- name: ObjC-ExampleApp testing -> iPhone 16 (iOS 18.4)
run: xcodebuild test -scheme ObjC-ExampleApp -workspace ConsentViewController.xcworkspace -destination 'platform=iOS Simulator,name=iPhone 16,OS=18.4'
- run: |
sudo xcode-select -s /Applications/Xcode_26.4.1.app
xcodebuild -version
xcrun --find swiftc
xcrun --show-sdk-path --sdk iphonesimulator
xcrun simctl list runtimes
- name: ObjC-ExampleApp testing -> iPhone 17 (iOS 26.4.1)
run: xcodebuild test -scheme ObjC-ExampleApp -workspace ConsentViewController.xcworkspace -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.4.1'
- uses: actions/upload-artifact@v4
if: failure()
name: Upload ObjCExampleApp tests results
with:
path: /Users/runner/Library/Developer/Xcode/DerivedData/**/*.xcresult
ConsentViewController:
runs-on: macos-15
runs-on: macos-26
steps:
- uses: actions/checkout@v4
- run: sudo xcode-select -s /Applications/Xcode_16.3.app
- name: ConsentViewController testing -> iPhone 16 (iOS 18.4)
run: xcodebuild test -scheme ConsentViewController_Example -workspace ConsentViewController.xcworkspace -destination 'platform=iOS Simulator,name=iPhone 16,OS=18.4'
- run: sudo xcode-select -s /Applications/Xcode_26.4.1.app
- name: ConsentViewController testing -> iPhone 17 (iOS 26.4.1)
run: xcodebuild test -scheme ConsentViewController_Example -workspace ConsentViewController.xcworkspace -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.4.1'
- uses: actions/upload-artifact@v4
if: failure()
name: Upload ConsentViewController tests results
with:
path: /Users/runner/Library/Developer/Xcode/DerivedData/**/*.xcresult
AuthExample-tests:
runs-on: macos-15
runs-on: macos-26
steps:
- uses: actions/checkout@v4
- run: sudo xcode-select -s /Applications/Xcode_16.3.app
- name: ConsentViewController testing -> iPhone 16 (iOS 18.4)
run: xcodebuild test -scheme AuthExample -workspace ConsentViewController.xcworkspace -destination 'platform=iOS Simulator,name=iPhone 16,OS=18.4'
- run: sudo xcode-select -s /Applications/Xcode_26.4.1.app
- name: ConsentViewController testing -> iPhone 17 (iOS 26.4.1)
run: xcodebuild test -scheme AuthExample -workspace ConsentViewController.xcworkspace -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.4.1'
- uses: actions/upload-artifact@v4
if: failure()
name: Upload ConsentViewController tests results
with:
path: /Users/runner/Library/Developer/Xcode/DerivedData/**/*.xcresult
TVOSExampleApp:
runs-on: macos-15
runs-on: macos-26
steps:
- uses: actions/checkout@v4
- run: sudo xcode-select -s /Applications/Xcode_16.3.app
- name: ConsentViewController testing -> Apple TV (tvOS 18.4)
run: xcodebuild test -scheme TVOSExampleApp -workspace ConsentViewController.xcworkspace -destination 'platform=tvOS Simulator,name=Apple TV,OS=18.4'
- run: sudo xcode-select -s /Applications/Xcode_26.4.1.app
- name: ConsentViewController testing -> Apple TV (tvOS 26.4.1)
run: xcodebuild test -scheme TVOSExampleApp -workspace ConsentViewController.xcworkspace -destination 'platform=tvOS Simulator,name=Apple TV,OS=26.4'
- uses: actions/upload-artifact@v4
if: failure()
name: Upload TVOSExampleApp tests results
Expand Down
3 changes: 2 additions & 1 deletion ConsentViewController.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Pod::Spec.new do |s|
}
s.pod_target_xcconfig = {
'BUILD_LIBRARY_FOR_DISTRIBUTION' => 'YES',
'DEFINES_MODULE' => 'YES'
'DEFINES_MODULE' => 'YES',
'OTHER_SWIFT_FLAGS[config=Debug]' => '$(inherited) -enable-testing'
}
end
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ extension KotlinFloat {
extension SPError {
func toCore() -> CoreSPError {
return CoreSPError(
code: String(code),
code: spCode,
description: description,
cause: nil,
campaignType: campaignType.toCore()
Expand Down
30 changes: 15 additions & 15 deletions Example/AuthExampleUITests/AuthExampleUITests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,48 +12,48 @@ import Quick
import XCTest

class AuthExampleUITests: QuickSpec {
var app: AuthExampleApp!
static var app: AuthExampleApp!

override func spec() {
override class func spec() {
beforeSuite {
self.app = AuthExampleApp()
Nimble.AsyncDefaults.timeout = .seconds(20)
Nimble.AsyncDefaults.pollInterval = .milliseconds(100)
app = AuthExampleApp()
Nimble.PollingDefaults.timeout = .seconds(20)
Nimble.PollingDefaults.pollInterval = .milliseconds(100)
}

afterSuite {
Nimble.AsyncDefaults.timeout = .seconds(1)
Nimble.AsyncDefaults.pollInterval = .milliseconds(10)
Nimble.PollingDefaults.timeout = .seconds(1)
Nimble.PollingDefaults.pollInterval = .milliseconds(10)
}

beforeEach {
self.app.relaunch(clean: true, resetAtt: true)
app.relaunch(clean: true, resetAtt: true)
}

func acceptGDPRMessage() {
expect(self.app.gdprMessage.messageTitle).toEventually(showUp())
self.app.gdprMessage.acceptButton.tap()
expect(app.gdprMessage.messageTitle).toEventually(showUp())
app.gdprMessage.acceptButton.tap()
}

func acceptCCPAMessage() {
expect(self.app.ccpaMessage.messageTitle).toEventually(showUp())
self.app.ccpaMessage.acceptButton.tap()
expect(app.ccpaMessage.messageTitle).toEventually(showUp())
app.ccpaMessage.acceptButton.tap()
}

func waitForSdkToFinish() {
expect(self.app.sdkStatusLabel).toEventually(containText("Finished"))
expect(app.sdkStatusLabel).toEventually(containText("Finished"))
}

func navigateToWebView() {
self.app.webViewButton.tap()
app.webViewButton.tap()
}

it("Accepting all via native screen should prevent messages from showing on the webview screen") {
acceptGDPRMessage()
acceptCCPAMessage()
waitForSdkToFinish()
navigateToWebView()
expect(self.app.webViewOnConsentReadyCalls.count).toEventually(equal(2))
expect(app.webViewOnConsentReadyCalls.count).toEventually(equal(2))
}
}
}
53 changes: 13 additions & 40 deletions Example/AuthExampleUITests/CustomMatchers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,66 +11,39 @@ import Nimble
import Quick
import XCTest

public typealias Predicate = Nimble.Predicate

extension DispatchTimeInterval {
func toDouble() -> Double {
var result: Double = 0
switch self {
case .seconds(let value):
result = Double(value)

case .milliseconds(let value):
result = Double(value) * 0.001

case .microseconds(let value):
result = Double(value) * 0.000_001

case .nanoseconds(let value):
result = Double(value) * 0.000_000_001

case .never:
result = Double.infinity
@unknown default:
result = Double.infinity
}
return result
}
}

/// A matcher that checks if a `XCUIElement` contains the given text
public func containText(_ text: String) -> Predicate<XCUIElement> {
Predicate.simple("contain text") { actualExpression in
public func containText(_ text: String) -> Matcher<XCUIElement> {
Matcher.simple("contain text") { actualExpression in
guard let actual = try actualExpression.evaluate() else { return .fail }
return PredicateStatus(bool: actual.label.contains(text))
return MatcherStatus(bool: actual.label.contains(text))
}
}

/// A Nimble matcher that succeeds when an XCUIElement shows up after
/// a certain amount of time. 20 seconds by default
public func showUp() -> Predicate<XCUIElement> {
Predicate.simple("show up") { actualExpression in
public func showUp() -> Matcher<XCUIElement> {
Matcher.simple("show up") { actualExpression in
guard let actual = try actualExpression.evaluate() else { return .fail }
return PredicateStatus(bool: actual.waitForExistence(timeout: Nimble.AsyncDefaults.timeout.toDouble()))
return MatcherStatus(bool: actual.waitForExistence(timeout: Nimble.PollingDefaults.timeout.timeInterval))
}
}

/// A Nimble matcher that succeeds when an XCUIElement shows up after
/// a certain amount of time.
public func showUp(in timeout: TimeInterval) -> Predicate<XCUIElement> {
Predicate.simple("show up") { actualExpression in
public func showUp(in timeout: TimeInterval) -> Matcher<XCUIElement> {
Matcher.simple("show up") { actualExpression in
guard let actual = try actualExpression.evaluate() else { return .fail }
return PredicateStatus(bool: actual.waitForExistence(timeout: timeout))
return MatcherStatus(bool: actual.waitForExistence(timeout: timeout))
}
}

/// A Nimble matcher that succeeds when an XCUIElement no longer exists. Due to its async nature, it should
/// be used together with `.toEventually`.
public func disappear() -> Predicate<XCUIElement> {
Predicate.simple("disappear") { actualExpression in
public func disappear() -> Matcher<XCUIElement> {
Matcher.simple("disappear") { actualExpression in
guard let actual = try actualExpression.evaluate() else { return .fail }
QuickSpec.current.expectation(for: NSPredicate(format: "exists == FALSE"), evaluatedWith: actual, handler: nil)
QuickSpec.current.waitForExpectations(timeout: Double(Nimble.AsyncDefaults.timeout.toDouble()))
return PredicateStatus(bool: !actual.exists)
QuickSpec.current.waitForExpectations(timeout: Nimble.PollingDefaults.timeout.timeInterval)
return MatcherStatus(bool: !actual.exists)
}
}
Loading
Loading