Skip to content
Open
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
8 changes: 7 additions & 1 deletion scripts/android/tests/PostPrComment.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
Expand Down Expand Up @@ -324,7 +325,12 @@ private static Map<String, String> publishPreviewsToBranch(Path previewDir, Stri
try (var stream = Files.list(dest)) {
stream.filter(Files::isRegularFile)
.sorted()
.forEach(path -> urls.put(path.getFileName().toString(), rawBase + "/" + path.getFileName()));
.forEach(path -> {
String fileName = path.getFileName().toString();
String url = rawBase + "/" + fileName;
urls.put(fileName, url);
urls.put(fileName.toLowerCase(Locale.ROOT), url);
});
}
deleteRecursively(worktree);
return urls;
Expand Down
82 changes: 81 additions & 1 deletion scripts/ios/tests/HelloCodenameOneUITests.swift.tmpl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import XCTest
import UIKit
import CoreGraphics

final class HelloCodenameOneUITests: XCTestCase {
private var app: XCUIApplication!
Expand Down Expand Up @@ -37,7 +38,7 @@ final class HelloCodenameOneUITests: XCTestCase {
}

private func captureScreenshot(named name: String) throws {
let shot = XCUIScreen.main.screenshot()
let shot = waitForRenderedScreenshot(label: name)

// Save into sandbox tmp (optional – mainly for local debugging)
let pngURL = outputDirectory.appendingPathComponent("\(name).png")
Expand Down Expand Up @@ -79,6 +80,85 @@ final class HelloCodenameOneUITests: XCTestCase {
try captureScreenshot(named: "BrowserComponent")
}

private func waitForRenderedScreenshot(label: String, timeout: TimeInterval = 10, poll: TimeInterval = 0.4) -> XCUIScreenshot {
let deadline = Date(timeIntervalSinceNow: timeout)
RunLoop.current.run(until: Date(timeIntervalSinceNow: 1.0))
var attempt = 0
var screenshot = XCUIScreen.main.screenshot()
while Date() < deadline {
if screenshotHasRenderableContent(screenshot) {
return screenshot
}
attempt += 1
print("CN1SS:INFO:test=\(label) waiting_for_rendered_frame attempt=\(attempt)")
RunLoop.current.run(until: Date(timeIntervalSinceNow: poll))
screenshot = XCUIScreen.main.screenshot()
}
return screenshot
}

private func screenshotHasRenderableContent(_ screenshot: XCUIScreenshot) -> Bool {
guard let cgImage = screenshot.image.cgImage else {
return true
}
let width = cgImage.width
let height = cgImage.height
guard width > 0, height > 0 else {
return false
}

let insetX = max(0, width / 8)
let insetY = max(0, height / 8)
let cropRect = CGRect(
x: insetX,
y: insetY,
width: max(1, width - insetX * 2),
height: max(1, height - insetY * 2)
).integral
guard let cropped = cgImage.cropping(to: cropRect) else {
return true
}

let sampleWidth = 80
let sampleHeight = 80
let bytesPerPixel = 4
let bytesPerRow = sampleWidth * bytesPerPixel
guard let context = CGContext(
data: nil,
width: sampleWidth,
height: sampleHeight,
bitsPerComponent: 8,
bytesPerRow: bytesPerRow,
space: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue
) else {
return true
}
context.interpolationQuality = .high
context.draw(cropped, in: CGRect(x: 0, y: 0, width: sampleWidth, height: sampleHeight))
guard let data = context.data else {
return true
}

let buffer = data.bindMemory(to: UInt8.self, capacity: sampleHeight * bytesPerRow)
var minLuma = 255
var maxLuma = 0
for y in 0..<sampleHeight {
let row = y * bytesPerRow
for x in 0..<sampleWidth {
let idx = row + x * bytesPerPixel
let r = Int(buffer[idx])
let g = Int(buffer[idx + 1])
let b = Int(buffer[idx + 2])
let luma = (r * 299 + g * 587 + b * 114) / 1000
if luma < minLuma { minLuma = luma }
if luma > maxLuma { maxLuma = luma }
}
}

return maxLuma - minLuma > 12
}

private func sanitizeTestName(_ name: String) -> String {
let allowed = CharacterSet(charactersIn: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.-")
let underscore: UnicodeScalar = "_"
Expand Down
Loading