-
Notifications
You must be signed in to change notification settings - Fork 134
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
RUMM-1649 WebViewTracking integration test added
- Loading branch information
Showing
6 changed files
with
263 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* | ||
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. | ||
* This product includes software developed at Datadog (https://www.datadoghq.com/). | ||
* Copyright 2019-2020 Datadog, Inc. | ||
*/ | ||
|
||
import Foundation | ||
import Datadog | ||
|
||
/// Scenario which uses RUM only. Blocks the main thread and expects to have non-zero MobileVitals values | ||
final class WebViewTrackingScenario: TestScenario { | ||
static var storyboardName: String = "WebViewTrackingScenario" | ||
|
||
func configureSDK(builder: Datadog.Configuration.Builder) { | ||
_ = builder | ||
.trackUIKitRUMViews() | ||
.enableLogging(true) | ||
.enableRUM(true) | ||
} | ||
} |
138 changes: 138 additions & 0 deletions
138
Datadog/Example/Scenarios/WebView/WebViewTrackingFixtureViewController.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
/* | ||
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. | ||
* This product includes software developed at Datadog (https://www.datadoghq.com/). | ||
* Copyright 2019-2020 Datadog, Inc. | ||
*/ | ||
|
||
import UIKit | ||
import WebKit | ||
import Datadog | ||
|
||
class WebViewTrackingFixtureViewController: UIViewController, WKNavigationDelegate { | ||
let html = """ | ||
<head> | ||
<meta charset="utf-8"> | ||
<title>Mobile SDK Detection test page</title> | ||
<link rel="icon" type="image/x-icon" href="./favicon.ico"> | ||
<script type="text/javascript"> | ||
function show(message) { | ||
const p = document.createElement("p"); | ||
p.innerHTML = message; | ||
if (document.body) { | ||
document.body.appendChild(p); | ||
} else { | ||
window.addEventListener("DOMContentLoaded", () => | ||
document.body.appendChild(p) | ||
); | ||
} | ||
} | ||
function isEventBridgePresent() { | ||
const isPresent = window.DatadogEventBridge; | ||
if (!isPresent) { | ||
show(`window.DatadogEventBridge absent!`); | ||
return false; | ||
} | ||
if (!isViewHostAllowed()) { | ||
show( | ||
`This page does not respect window.DatadogEventBridge.getAllowedWebViewHosts: <br>${window.DatadogEventBridge.getAllowedWebViewHosts()}` | ||
); | ||
return false; | ||
} | ||
return true; | ||
} | ||
function getEventBridge() { | ||
const datadogEventBridge = window.DatadogEventBridge; | ||
return { | ||
getAllowedWebViewHosts() { | ||
try { | ||
return JSON.parse( | ||
window.DatadogEventBridge.getAllowedWebViewHosts() | ||
); | ||
} catch (e) { | ||
show( | ||
`allowWebViewHosts is not a valid json ${window.DatadogEventBridge.getAllowedWebViewHosts()}` | ||
); | ||
} | ||
return []; | ||
}, | ||
send(eventType, event) { | ||
const eventStr = JSON.stringify({ | ||
eventType, | ||
event, | ||
tags: ["browser_sdk_version:3.6.13"], | ||
}); | ||
datadogEventBridge.send(eventStr); | ||
show( | ||
`window.DatadogEventBridge: ${eventType} sent! <br><br>${eventStr}` | ||
); | ||
}, | ||
}; | ||
} | ||
function sendLog() { | ||
if (!isEventBridgePresent()) { | ||
return; | ||
} | ||
try { | ||
const log = { | ||
date: 1635932927012, | ||
error: { origin: "console" }, | ||
message: "console error: error", | ||
session_id: "0110cab4-7471-480e-aa4e-7ce039ced355", | ||
status: "error", | ||
view: { | ||
referrer: "", | ||
url: "https://datadoghq.dev/browser-sdk-test-playground", | ||
}, | ||
}; | ||
getEventBridge().send("log", log); | ||
} catch (err) { | ||
show(`window.DatadogEventBridge: Could not send ${err}`); | ||
} | ||
} | ||
function isViewHostAllowed() { | ||
return getEventBridge() | ||
.getAllowedWebViewHosts() | ||
.some((o) => o.includes(window.location.hostname)); | ||
} | ||
show( | ||
`window.DatadogEventBridge: <br>${JSON.stringify( | ||
window.DatadogEventBridge | ||
)}` | ||
); | ||
</script> | ||
</head> | ||
<body> | ||
<button onclick="sendLog()">Send dummy log</button> | ||
<p>window.DatadogEventBridge: <br>undefined</p></body> | ||
""" | ||
|
||
private var webView: WKWebView! | ||
|
||
override func viewDidLoad() { | ||
super.viewDidLoad() | ||
|
||
let controller = WKUserContentController() | ||
controller.addDatadogMessageHandler(allowedWebViewHosts: ["datadoghq.dev"]) | ||
let config = WKWebViewConfiguration() | ||
config.userContentController = controller | ||
|
||
webView = WKWebView(frame: view.bounds, configuration: config) | ||
webView.navigationDelegate = self | ||
view.addSubview(webView) | ||
} | ||
|
||
override func viewWillAppear(_ animated: Bool) { | ||
super.viewWillAppear(animated) | ||
webView.loadHTMLString(html, baseURL: nil) | ||
} | ||
|
||
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { | ||
let js = """ | ||
window.sendLog() | ||
""" | ||
webView.evaluateJavaScript(js) { res, err in | ||
assert(err == nil, "JS execution shouldn't return an error") | ||
} | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
Datadog/Example/Scenarios/WebView/WebViewTrackingScenario.storyboard
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Y6W-OH-hqX"> | ||
<device id="retina6_1" orientation="portrait" appearance="light"/> | ||
<dependencies> | ||
<deployment identifier="iOS"/> | ||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/> | ||
<capability name="Safe area layout guides" minToolsVersion="9.0"/> | ||
<capability name="System colors in document resources" minToolsVersion="11.0"/> | ||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> | ||
</dependencies> | ||
<scenes> | ||
<!--Web View Tracking Fixture View Controller--> | ||
<scene sceneID="s0d-6b-0kx"> | ||
<objects> | ||
<viewController id="Y6W-OH-hqX" customClass="WebViewTrackingFixtureViewController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController"> | ||
<view key="view" contentMode="scaleToFill" id="5EZ-qb-Rvc"> | ||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/> | ||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | ||
<viewLayoutGuide key="safeArea" id="vDu-zF-Fre"/> | ||
<color key="backgroundColor" systemColor="systemBackgroundColor"/> | ||
</view> | ||
</viewController> | ||
<placeholder placeholderIdentifier="IBFirstResponder" id="Ief-a0-LHa" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/> | ||
</objects> | ||
<point key="canvasLocation" x="114" y="80"/> | ||
</scene> | ||
</scenes> | ||
<resources> | ||
<systemColor name="systemBackgroundColor"> | ||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | ||
</systemColor> | ||
</resources> | ||
</document> |
35 changes: 35 additions & 0 deletions
35
Tests/DatadogIntegrationTests/Scenarios/WebView/WebViewScenarioTest.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* | ||
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. | ||
* This product includes software developed at Datadog (https://www.datadoghq.com/). | ||
* Copyright 2019-2020 Datadog, Inc. | ||
*/ | ||
|
||
import Foundation | ||
import HTTPServerMock | ||
import XCTest | ||
|
||
class WebViewScenarioTest: IntegrationTests, LoggingCommonAsserts { | ||
func testWebViewLoggingScenario() throws { | ||
let loggingServerSession = server.obtainUniqueRecordingSession() | ||
|
||
let app = ExampleApplication() | ||
app.launchWith( | ||
testScenarioClassName: "WebViewTrackingScenario", | ||
serverConfiguration: HTTPServerMockConfiguration( | ||
logsEndpoint: loggingServerSession.recordingURL | ||
) | ||
) | ||
|
||
// Get expected number of `LogMatchers` | ||
let recordedRequests = try loggingServerSession.pullRecordedRequests(timeout: dataDeliveryTimeout) { requests in | ||
try LogMatcher.from(requests: requests).count >= 1 | ||
} | ||
let logMatchers = try LogMatcher.from(requests: recordedRequests) | ||
|
||
// Assert common things | ||
assertLogging(requests: recordedRequests) | ||
|
||
logMatchers[0].assertStatus(equals: "error") | ||
logMatchers[0].assertMessage(equals: "console error: error") | ||
} | ||
} |