Skip to content
Draft
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
1 change: 1 addition & 0 deletions .github/workflows/env.properties
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
xcode_version=16.4.0
accessibility_snapshot_ios_version=16.2
14 changes: 13 additions & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,15 @@ jobs:
- name: Build & Test
run: tuist test --path SampleApp --os ${{ matrix.sdk }} UnitTests -- -resultBundlePath TestResult

- name: Build & Test Accessibility Snapshots (iOS ${{ env.accessibility_snapshot_ios_version }} only)
if: ${{ matrix.sdk == env.accessibility_snapshot_ios_version }}
run: tuist test --path SampleApp --os ${{ matrix.sdk }} AccessibilitySnapshotTests -- -resultBundlePath AccessibilityTestResult

- name: Package snapshot changes
if: ${{ failure() }}
run: |
git ls-files -mo BlueprintUICommonControls/Tests/Sources/Resources/ReferenceImages | xargs tar -cvf snapshot_changes_${{ matrix.sdk }}.tar
git ls-files -mo BlueprintUICommonControls/AccessibilitySnapshotTests/__Snapshots__ | xargs tar -cvf accessibility_snapshot_changes_${{ matrix.sdk }}.tar

- name: Archive snapshot changes
uses: actions/upload-artifact@v4
Expand All @@ -78,5 +83,12 @@ jobs:
uses: actions/upload-artifact@v4
if: ${{ failure() }}
with:
name: TestResult.xcresult
name: TestResult-${{ matrix.sdk }}.xcresult
path: TestResult.xcresult

- name: Archive AccessibilityTestResult
uses: actions/upload-artifact@v4
if: ${{ failure() && matrix.sdk == env.accessibility_snapshot_ios_version }}
with:
name: AccessibilityTestResult-${{ matrix.sdk }}.xcresult
path: AccessibilityTestResult.xcresult
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import AccessibilitySnapshot
import BlueprintUI
import BlueprintUICommonControls
import SnapshotTesting
import XCTest

/// Accessibility snapshot tests for accessibility modifier controls.
/// Tests various accessibility configurations to ensure proper accessibility support.
class AccessibilityModifierSnapshotTests: XCTestCase {

func test_accessibility_element_basic() {
let content = Label(text: "Basic Element")
.accessibilityElement(
label: "Custom Label",
value: "Custom Value",
traits: [.button]
)

assertAccessibilitySnapshot(of: content)
}

func test_accessibility_element_with_hint() {
let content = Label(text: "Save Document")
.accessibilityElement(
label: "Save Document",
value: nil,
traits: [.button],
hint: "Saves the current document to disk"
)

assertAccessibilitySnapshot(of: content)
}

func test_accessibility_hidden() {
let content = Column(minimumSpacing: 8) {
Label(text: "Visible Label")

Label(text: "Hidden Decorative Element")
.blockAccessibility()

Label(text: "Another Visible Label")
}

assertAccessibilitySnapshot(of: content)
}

func test_accessibility_container() {
let content = Column(minimumSpacing: 12) {
Label(text: "Container ")

Row(minimumSpacing: 8) {
Label(text: "Item 1")
Label(text: "Item 2")
Label(text: "Item 3")
}
.accessibilityContainer(label: "Container Title")
}

assertAccessibilitySnapshot(of: content)
}

func test_accessibility_label_override() {
let content = Column(minimumSpacing: 8) {
Label(text: "42°F")
.accessibilityElement(label: "42 degrees Fahrenheit", value: nil, traits: [])


Label(text: "NASA")
.accessibilityElement(label: "National Aeronautics and Space Administration", value: nil, traits: [])


Label(text: "🎉")
.accessibilityElement(label: "Celebration", value: nil, traits: [])

}

assertAccessibilitySnapshot(of: content)
}

func test_accessibility_value_override() {
let content = Column(minimumSpacing: 8) {
Label(text: "Progress: 75%")
.accessibilityElement(label: "Progress", value: "75 percent complete", traits: [])

Label(text: "Battery: 50%")
.accessibilityElement(label: "Battery", value: "50 percent charged", traits: [])

}

assertAccessibilitySnapshot(of: content)
}

func test_accessibility_traits() {
let content = Column(minimumSpacing: 12) {
Label(text: "Header Text")
.accessibilityElement(label: "Header Text", value: nil, traits: [.header])

Label(text: "Button Text")
.accessibilityElement(label: "Button Text", value: nil, traits: [.button])

Label(text: "Back Button Text")
.accessibilityElement(label: "Button Text", value: nil, traits: [.backButton])

Label(text: "Toggle Text")
.accessibilityElement(label: "Toggle Text", value: nil, traits: [.toggleButton])

Label(text: "Link Text")
.accessibilityElement(label: "Link Text", value: nil, traits: [.link])

Label(text: "Selected Item")
.accessibilityElement(label: "Selected Text", value: nil, traits: [.selected])

Label(text: "Disabled Item")
.accessibilityElement(label: "Disabled Text", value: nil, traits: [.notEnabled])
}

assertAccessibilitySnapshot(of: content)
}

func test_accessibility_complex_element() {
let element =
Column(minimumSpacing: 8) {
Row(minimumSpacing: 8) {
Label(text: "👤")

Label(text: "John Doe")

Spacer()

Label(text: "Online")
}

Label(text: "Software Engineer at Tech Corp")

Label(text: "Last seen 2 minutes ago")
}
.inset(uniform: 12)
.accessibilityElement(
label: "John Doe",
value: "Software Engineer at Tech Corp, Online, Last seen 2 minutes ago",
traits: [.button],
hint: "Tap to view profile"
)

assertAccessibilitySnapshot(of: element)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import AccessibilitySnapshot
import BlueprintUI
import BlueprintUICommonControls
import SnapshotTesting
import XCTest

/// Accessibility snapshot tests for AttributedLabel control.
/// Tests various attributed label configurations to ensure proper accessibility support.
class AttributedLabelAccessibilitySnapshotTests: XCTestCase {

func test_attributed_label_basic() {
let attributedText = NSAttributedString(
string: "Basic attributed text",
attributes: [.foregroundColor: UIColor.label]
)

let label = AttributedLabel(attributedText: attributedText)

assertAccessibilitySnapshot(of: label)
}


func test_attributed_label_with_links() {
let attributedText = NSMutableAttributedString(string: "Visit our website at example.com for more information.")

attributedText.addAttributes([
.link: NSURL(string: "https://example.com")!,
], range: attributedText.mutableString.range(of: "example.com"))

let label = AttributedLabel(attributedText: attributedText)
assertAccessibilitySnapshot(of: label)
}

func test_attributed_label_multiline() {
let attributedText = NSMutableAttributedString()

attributedText.append(NSAttributedString(
string: "First Line\n",
attributes: [.font: UIFont.boldSystemFont(ofSize: 18)]
))

attributedText.append(NSAttributedString(
string: "Second line with regular text\n",
attributes: [.font: UIFont.systemFont(ofSize: 16)]
))

attributedText.append(NSAttributedString(
string: "Third line in italic",
attributes: [.font: UIFont.italicSystemFont(ofSize: 14)]
))

let label = AttributedLabel(attributedText: attributedText)

assertAccessibilitySnapshot(of: label)
}

func test_attributed_label_with_mixed_content() {
let attributedText = NSMutableAttributedString()

// Title
attributedText.append(NSAttributedString(
string: "Product Review\n",
attributes: [
.font: UIFont.boldSystemFont(ofSize: 20),
.foregroundColor: UIColor.label,
]
))

// Rating
attributedText.append(NSAttributedString(
string: "⭐⭐⭐⭐⭐ ",
attributes: [.font: UIFont.systemFont(ofSize: 16)]
))

// Score
attributedText.append(NSAttributedString(
string: "5.0/5.0\n",
attributes: [
.font: UIFont.boldSystemFont(ofSize: 16),
.foregroundColor: UIColor.systemGreen,
]
))

// Description
attributedText.append(NSAttributedString(
string: "Excellent product with great quality and fast shipping.",
attributes: [
.font: UIFont.systemFont(ofSize: 14),
.foregroundColor: UIColor.secondaryLabel,
]
))

let label = AttributedLabel(attributedText: attributedText)


assertAccessibilitySnapshot(of: label)
}

func test_attributed_label_with_strikethrough() {
let attributedText = NSMutableAttributedString()

attributedText.append(NSAttributedString(
string: "Original Price: ",
attributes: [.font: UIFont.systemFont(ofSize: 16)]
))

attributedText.append(NSAttributedString(
string: "$29.99",
attributes: [
.font: UIFont.systemFont(ofSize: 16),
.strikethroughStyle: NSUnderlineStyle.single.rawValue,
.foregroundColor: UIColor.secondaryLabel,
]
))

attributedText.append(NSAttributedString(
string: " Sale Price: ",
attributes: [.font: UIFont.systemFont(ofSize: 16)]
))

attributedText.append(NSAttributedString(
string: "$19.99",
attributes: [
.font: UIFont.boldSystemFont(ofSize: 16),
.foregroundColor: UIColor.systemRed,
]
))

let label = AttributedLabel(attributedText: attributedText)

assertAccessibilitySnapshot(of: label)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import AccessibilitySnapshot
import BlueprintUI
import BlueprintUICommonControls
import SnapshotTesting
import XCTest

/// Accessibility snapshot tests for Button control.
/// Tests various button configurations to ensure proper accessibility support.
class ButtonAccessibilitySnapshotTests: XCTestCase {

func test_button_basic() {
let button = Button(wrapping: Label(text: "Basic Button"))

assertAccessibilitySnapshot(of: button)
}

func test_button_with_icon_and_text() {
let content = Row(minimumSpacing: 8) {
Label(text: "📁")
Label(text: "Open File")
}

let button = Button(wrapping: content)

assertAccessibilitySnapshot(of: button)
}

func test_button_with_multipleText() {
let content = Row(minimumSpacing: 8) {
Label(text: "One")
Label(text: "Two")
}

let button = Button(wrapping: content)

assertAccessibilitySnapshot(of: button)
}


func test_button_multiline_text() {
let button = Button(wrapping:
Label(text: "This is a button with\nmultiple lines of text")
)

assertAccessibilitySnapshot(of: button)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import AccessibilitySnapshot
import BlueprintUI
import BlueprintUICommonControls
import SnapshotTesting
import XCTest

/// Accessibility snapshot tests for Label control.
/// Tests various label configurations to ensure proper accessibility support.
class LabelAccessibilitySnapshotTests: XCTestCase {

func test_label_basic() {
let label = Label(text: "Basic Label")

assertAccessibilitySnapshot(of: label)
}

func test_label_multiline() {
let label = Label(text: "This is a longer label that spans multiple lines\nto test accessibility with wrapped text content.")


assertAccessibilitySnapshot(of: label)
}

}
Loading
Loading