<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[243405] trunk/LayoutTests</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/243405">243405</a></dd>
<dt>Author</dt> <dd>drousso@apple.com</dd>
<dt>Date</dt> <dd>2019-03-22 16:34:29 -0700 (Fri, 22 Mar 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>Unreviewed, fix test failures after <a href="http://trac.webkit.org/projects/webkit/changeset/243269">r243269</a>.

In debug builds, it's possible that the Web Inspector frontend is told to stop a timeline
recording before all of the recorded records have had a chance to be completed/processed.

As an example
```
    setTimeout(() => {
        <stop recording>
    });
```
it may happen that the "stop recording" event will be dispatched before the timeout has
finished executing, meaning that the event that contains the recorded data for that timeout
will be ignored by the frontend.

Rework the tests so that they don't dispatch the "stop recording" event until the expected
record is received by the frontend, rather than having the test code itself say when to stop.

* inspector/timeline/resources/timeline-event-utilities.js:
(savePageData): Added.
(TestPage.registerInitializer.InspectorTest.TimelineEvent.captureTimelineWithScript):
(finishRecording): Deleted.
* inspector/timeline/timeline-event-CancelAnimationFrame.html:
* inspector/timeline/timeline-event-CancelAnimationFrame-expected.txt:
* inspector/timeline/timeline-event-EventDispatch.html:
* inspector/timeline/timeline-event-EventDispatch-expected.txt:
* inspector/timeline/timeline-event-FireAnimationFrame.html:
* inspector/timeline/timeline-event-FireAnimationFrame-expected.txt:
* inspector/timeline/timeline-event-RequestAnimationFrame.html:
* inspector/timeline/timeline-event-RequestAnimationFrame-expected.txt:
* inspector/timeline/timeline-event-TimerFire.html:
* inspector/timeline/timeline-event-TimerFire-expected.txt:
* inspector/timeline/timeline-event-TimerInstall.html:
* inspector/timeline/timeline-event-TimerInstall-expected.txt:
* inspector/timeline/timeline-event-TimerRemove.html:
* inspector/timeline/timeline-event-TimerRemove-expected.txt:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsinspectortimelineresourcestimelineeventutilitiesjs">trunk/LayoutTests/inspector/timeline/resources/timeline-event-utilities.js</a></li>
<li><a href="#trunkLayoutTestsinspectortimelinetimelineeventCancelAnimationFrameexpectedtxt">trunk/LayoutTests/inspector/timeline/timeline-event-CancelAnimationFrame-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectortimelinetimelineeventCancelAnimationFramehtml">trunk/LayoutTests/inspector/timeline/timeline-event-CancelAnimationFrame.html</a></li>
<li><a href="#trunkLayoutTestsinspectortimelinetimelineeventEventDispatchexpectedtxt">trunk/LayoutTests/inspector/timeline/timeline-event-EventDispatch-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectortimelinetimelineeventEventDispatchhtml">trunk/LayoutTests/inspector/timeline/timeline-event-EventDispatch.html</a></li>
<li><a href="#trunkLayoutTestsinspectortimelinetimelineeventFireAnimationFrameexpectedtxt">trunk/LayoutTests/inspector/timeline/timeline-event-FireAnimationFrame-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectortimelinetimelineeventFireAnimationFramehtml">trunk/LayoutTests/inspector/timeline/timeline-event-FireAnimationFrame.html</a></li>
<li><a href="#trunkLayoutTestsinspectortimelinetimelineeventRequestAnimationFrameexpectedtxt">trunk/LayoutTests/inspector/timeline/timeline-event-RequestAnimationFrame-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectortimelinetimelineeventRequestAnimationFramehtml">trunk/LayoutTests/inspector/timeline/timeline-event-RequestAnimationFrame.html</a></li>
<li><a href="#trunkLayoutTestsinspectortimelinetimelineeventTimerFireexpectedtxt">trunk/LayoutTests/inspector/timeline/timeline-event-TimerFire-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectortimelinetimelineeventTimerFirehtml">trunk/LayoutTests/inspector/timeline/timeline-event-TimerFire.html</a></li>
<li><a href="#trunkLayoutTestsinspectortimelinetimelineeventTimerInstallexpectedtxt">trunk/LayoutTests/inspector/timeline/timeline-event-TimerInstall-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectortimelinetimelineeventTimerInstallhtml">trunk/LayoutTests/inspector/timeline/timeline-event-TimerInstall.html</a></li>
<li><a href="#trunkLayoutTestsinspectortimelinetimelineeventTimerRemoveexpectedtxt">trunk/LayoutTests/inspector/timeline/timeline-event-TimerRemove-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectortimelinetimelineeventTimerRemovehtml">trunk/LayoutTests/inspector/timeline/timeline-event-TimerRemove.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (243404 => 243405)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2019-03-22 22:54:50 UTC (rev 243404)
+++ trunk/LayoutTests/ChangeLog 2019-03-22 23:34:29 UTC (rev 243405)
</span><span class="lines">@@ -1,5 +1,44 @@
</span><span class="cx"> 2019-03-22  Devin Rousso  <drousso@apple.com>
</span><span class="cx"> 
</span><ins>+        Unreviewed, fix test failures after r243269.
+
+        In debug builds, it's possible that the Web Inspector frontend is told to stop a timeline
+        recording before all of the recorded records have had a chance to be completed/processed.
+
+        As an example
+        ```
+            setTimeout(() => {
+                <stop recording>
+            });
+        ```
+        it may happen that the "stop recording" event will be dispatched before the timeout has
+        finished executing, meaning that the event that contains the recorded data for that timeout
+        will be ignored by the frontend.
+
+        Rework the tests so that they don't dispatch the "stop recording" event until the expected
+        record is received by the frontend, rather than having the test code itself say when to stop.
+
+        * inspector/timeline/resources/timeline-event-utilities.js:
+        (savePageData): Added.
+        (TestPage.registerInitializer.InspectorTest.TimelineEvent.captureTimelineWithScript):
+        (finishRecording): Deleted.
+        * inspector/timeline/timeline-event-CancelAnimationFrame.html:
+        * inspector/timeline/timeline-event-CancelAnimationFrame-expected.txt:
+        * inspector/timeline/timeline-event-EventDispatch.html:
+        * inspector/timeline/timeline-event-EventDispatch-expected.txt:
+        * inspector/timeline/timeline-event-FireAnimationFrame.html:
+        * inspector/timeline/timeline-event-FireAnimationFrame-expected.txt:
+        * inspector/timeline/timeline-event-RequestAnimationFrame.html:
+        * inspector/timeline/timeline-event-RequestAnimationFrame-expected.txt:
+        * inspector/timeline/timeline-event-TimerFire.html:
+        * inspector/timeline/timeline-event-TimerFire-expected.txt:
+        * inspector/timeline/timeline-event-TimerInstall.html:
+        * inspector/timeline/timeline-event-TimerInstall-expected.txt:
+        * inspector/timeline/timeline-event-TimerRemove.html:
+        * inspector/timeline/timeline-event-TimerRemove-expected.txt:
+
+2019-03-22  Devin Rousso  <drousso@apple.com>
+
</ins><span class="cx">         Web Inspector: Safari Canvas Inspector seems to show the canvas being rendered twice per frame.
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=196082
</span><span class="cx">         <rdar://problem/49113496>
</span></span></pre></div>
<a id="trunkLayoutTestsinspectortimelineresourcestimelineeventutilitiesjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/timeline/resources/timeline-event-utilities.js (243404 => 243405)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/timeline/resources/timeline-event-utilities.js       2019-03-22 22:54:50 UTC (rev 243404)
+++ trunk/LayoutTests/inspector/timeline/resources/timeline-event-utilities.js  2019-03-22 23:34:29 UTC (rev 243405)
</span><span class="lines">@@ -1,31 +1,47 @@
</span><del>-function finishRecording(data) {
-    TestPage.addResult("Finish recording...");
-    TestPage.dispatchEventToFrontend("FinishRecording", data);
</del><ins>+function savePageData(data) {
+    TestPage.dispatchEventToFrontend("SavePageData", data);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> TestPage.registerInitializer(() => {
</span><span class="cx">     InspectorTest.TimelineEvent = {};
</span><span class="cx"> 
</span><del>-    InspectorTest.TimelineEvent.captureTimelineWithScript = function(expression) {
</del><ins>+    InspectorTest.TimelineEvent.captureTimelineWithScript = function({expression, eventType}) {
</ins><span class="cx">         let pageRecordingData = null;
</span><span class="cx"> 
</span><del>-        InspectorTest.log("Starting Capture...");
-        const newRecording = true;
-        WI.timelineManager.startCapturing(newRecording);
</del><ins>+        let promise = new WI.WrappedPromise;
</ins><span class="cx"> 
</span><del>-        let promises = [];
</del><ins>+        WI.timelineManager.awaitEvent(WI.TimelineManager.Event.CapturingStopped).then((capturingStoppedEvent) => {
+            InspectorTest.assert(pageRecordingData, "savePageData should have been called in the page before capturing was stopped.");
+            promise.resolve(pageRecordingData);
+        });
</ins><span class="cx"> 
</span><del>-        promises.push(WI.timelineManager.awaitEvent(WI.TimelineManager.Event.CapturingStopped));
-
-        promises.push(InspectorTest.awaitEvent("FinishRecording").then((event) => {
-            InspectorTest.log("Stopping Capture...");
</del><ins>+        InspectorTest.awaitEvent("SavePageData").then((event) => {
</ins><span class="cx">             pageRecordingData = event.data;
</span><del>-            WI.timelineManager.stopCapturing();
-        }));
</del><ins>+        });
</ins><span class="cx"> 
</span><del>-        InspectorTest.log("Evaluating...");
-        promises.push(InspectorTest.evaluateInPage(expression));
</del><ins>+        WI.timelineManager.awaitEvent(WI.TimelineManager.Event.CapturingStarted).then((capturingStartedEvent) => {
+            let recording = WI.timelineManager.activeRecording;
+            let scriptTimeline = recording.timelines.get(WI.TimelineRecord.Type.Script);
</ins><span class="cx"> 
</span><del>-        return Promise.all(promises).then(() => pageRecordingData);
</del><ins>+            let recordAddedListener = scriptTimeline.addEventListener(WI.Timeline.Event.RecordAdded, (recordAddedEvent) => {
+                let {record} = recordAddedEvent.data;
+                if (record.eventType !== eventType)
+                    return;
+
+                scriptTimeline.removeEventListener(WI.Timeline.Event.RecordAdded, recordAddedListener);
+
+                InspectorTest.log("Stopping Capture...");
+                WI.timelineManager.stopCapturing();
+            });
+
+            InspectorTest.log("Evaluating...");
+            return InspectorTest.evaluateInPage(expression);
+        });
+
+        InspectorTest.log("Starting Capture...");
+        const newRecording = true;
+        WI.timelineManager.startCapturing(newRecording);
+
+        return promise.promise;
</ins><span class="cx">     }
</span><span class="cx"> });
</span></span></pre></div>
<a id="trunkLayoutTestsinspectortimelinetimelineeventCancelAnimationFrameexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/timeline/timeline-event-CancelAnimationFrame-expected.txt (243404 => 243405)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/timeline/timeline-event-CancelAnimationFrame-expected.txt    2019-03-22 22:54:50 UTC (rev 243404)
+++ trunk/LayoutTests/inspector/timeline/timeline-event-CancelAnimationFrame-expected.txt       2019-03-22 23:34:29 UTC (rev 243405)
</span><span class="lines">@@ -5,7 +5,6 @@
</span><span class="cx"> -- Running test case: TimelineEvent.CancelAnimationFrame.requestAnimationFrame
</span><span class="cx"> Starting Capture...
</span><span class="cx"> Evaluating...
</span><del>-Finish recording...
</del><span class="cx"> Stopping Capture...
</span><span class="cx"> PASS: Should be 1 AnimationFrameCanceled record.
</span><span class="cx"> DETAILS: number
</span></span></pre></div>
<a id="trunkLayoutTestsinspectortimelinetimelineeventCancelAnimationFramehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/timeline/timeline-event-CancelAnimationFrame.html (243404 => 243405)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/timeline/timeline-event-CancelAnimationFrame.html    2019-03-22 22:54:50 UTC (rev 243404)
+++ trunk/LayoutTests/inspector/timeline/timeline-event-CancelAnimationFrame.html       2019-03-22 23:34:29 UTC (rev 243405)
</span><span class="lines">@@ -10,11 +10,9 @@
</span><span class="cx">         TestPage.addResult("FAIL: requestAnimationFrame fired");
</span><span class="cx">     });
</span><span class="cx"> 
</span><ins>+    savePageData({requestAnimationFrameIdentifier});
+
</ins><span class="cx">     cancelAnimationFrame(requestAnimationFrameIdentifier);
</span><del>-
-    setTimeout(() => {
-        finishRecording({requestAnimationFrameIdentifier});
-    });
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function test()
</span><span class="lines">@@ -24,7 +22,10 @@
</span><span class="cx">     suite.addTestCase({
</span><span class="cx">         name: "TimelineEvent.CancelAnimationFrame.requestAnimationFrame",
</span><span class="cx">         async test() {
</span><del>-            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript(`testRequestAnimationFrame()`);
</del><ins>+            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript({
+                expression: `testRequestAnimationFrame()`,
+                eventType: WI.ScriptTimelineRecord.EventType.AnimationFrameCanceled,
+            });
</ins><span class="cx"> 
</span><span class="cx">             InspectorTest.assert(typeof pageRecordingData.requestAnimationFrameIdentifier === "number");
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsinspectortimelinetimelineeventEventDispatchexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/timeline/timeline-event-EventDispatch-expected.txt (243404 => 243405)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/timeline/timeline-event-EventDispatch-expected.txt   2019-03-22 22:54:50 UTC (rev 243404)
+++ trunk/LayoutTests/inspector/timeline/timeline-event-EventDispatch-expected.txt      2019-03-22 23:34:29 UTC (rev 243405)
</span><span class="lines">@@ -7,7 +7,6 @@
</span><span class="cx"> Starting Capture...
</span><span class="cx"> Evaluating...
</span><span class="cx"> PASS: click handler fired
</span><del>-Finish recording...
</del><span class="cx"> Stopping Capture...
</span><span class="cx"> PASS: Should be 1 EventDispatched record.
</span><span class="cx"> DETAILS: {"type":"click","defaultPrevented":false}
</span><span class="lines">@@ -17,7 +16,6 @@
</span><span class="cx"> Starting Capture...
</span><span class="cx"> Evaluating...
</span><span class="cx"> PASS: click handler fired, will prevent default
</span><del>-Finish recording...
</del><span class="cx"> Stopping Capture...
</span><span class="cx"> PASS: Should be 1 EventDispatched record.
</span><span class="cx"> DETAILS: {"type":"click","defaultPrevented":true}
</span><span class="lines">@@ -27,7 +25,6 @@
</span><span class="cx"> Starting Capture...
</span><span class="cx"> Evaluating...
</span><span class="cx"> PASS: b1 onclick attribute handler fired
</span><del>-Finish recording...
</del><span class="cx"> Stopping Capture...
</span><span class="cx"> PASS: Should be 1 EventDispatched record.
</span><span class="cx"> DETAILS: {"type":"click","defaultPrevented":false}
</span><span class="lines">@@ -37,7 +34,6 @@
</span><span class="cx"> Starting Capture...
</span><span class="cx"> Evaluating...
</span><span class="cx"> PASS: b2 onclick attribute handler fired, will prevent default
</span><del>-Finish recording...
</del><span class="cx"> Stopping Capture...
</span><span class="cx"> PASS: Should be 1 EventDispatched record.
</span><span class="cx"> DETAILS: {"type":"click","defaultPrevented":true}
</span></span></pre></div>
<a id="trunkLayoutTestsinspectortimelinetimelineeventEventDispatchhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/timeline/timeline-event-EventDispatch.html (243404 => 243405)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/timeline/timeline-event-EventDispatch.html   2019-03-22 22:54:50 UTC (rev 243404)
+++ trunk/LayoutTests/inspector/timeline/timeline-event-EventDispatch.html      2019-03-22 23:34:29 UTC (rev 243405)
</span><span class="lines">@@ -6,6 +6,8 @@
</span><span class="cx"> <script>
</span><span class="cx"> 
</span><span class="cx"> function testClickEventHandler({preventDefault}) {
</span><ins>+    savePageData({preventDefault});
+
</ins><span class="cx">     let button = document.body.appendChild(document.createElement("button"));
</span><span class="cx">     button.addEventListener("click", (event) => {
</span><span class="cx">         TestPage.addResult("PASS: click handler fired" + (preventDefault ? ", will prevent default" : ""));
</span><span class="lines">@@ -12,21 +14,15 @@
</span><span class="cx"> 
</span><span class="cx">         if (preventDefault)
</span><span class="cx">             event.preventDefault();
</span><del>-
-        setTimeout(() => {
-            finishRecording({preventDefault});
-        });
-    });
</del><ins>+    }, {once: true});
</ins><span class="cx">     button.dispatchEvent(new MouseEvent("click", {bubbles: true, cancelable: true}));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function testClickEventAttributeHandler(id, {preventDefault}) {
</span><ins>+    savePageData({preventDefault});
+
</ins><span class="cx">     let button = document.getElementById(id);
</span><span class="cx">     button.dispatchEvent(new MouseEvent("click", {bubbles: true, cancelable: true}));
</span><del>-
-    setTimeout(() => {
-        finishRecording({preventDefault});
-    });
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function test()
</span><span class="lines">@@ -36,7 +32,10 @@
</span><span class="cx">     suite.addTestCase({
</span><span class="cx">         name: "TimelineEvent.EventDispatch.Handler.Regular",
</span><span class="cx">         async test() {
</span><del>-            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript(`testClickEventHandler({preventDefault: false})`);
</del><ins>+            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript({
+                expression: `testClickEventHandler({preventDefault: false})`,
+                eventType: WI.ScriptTimelineRecord.EventType.EventDispatched,
+            });
</ins><span class="cx"> 
</span><span class="cx">             InspectorTest.assert(typeof pageRecordingData.preventDefault === "boolean");
</span><span class="cx"> 
</span><span class="lines">@@ -54,7 +53,10 @@
</span><span class="cx">     suite.addTestCase({
</span><span class="cx">         name: "TimelineEvent.EventDispatch.Handler.DefaultPrevented",
</span><span class="cx">         async test() {
</span><del>-            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript(`testClickEventHandler({preventDefault: true})`);
</del><ins>+            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript({
+                expression: `testClickEventHandler({preventDefault: true})`,
+                eventType: WI.ScriptTimelineRecord.EventType.EventDispatched,
+            });
</ins><span class="cx"> 
</span><span class="cx">             InspectorTest.assert(typeof pageRecordingData.preventDefault === "boolean");
</span><span class="cx"> 
</span><span class="lines">@@ -72,7 +74,10 @@
</span><span class="cx">     suite.addTestCase({
</span><span class="cx">         name: "TimelineEvent.EventDispatch.AttributeHandler.Regular",
</span><span class="cx">         async test() {
</span><del>-            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript(`testClickEventAttributeHandler("b1", {preventDefault: false})`);
</del><ins>+            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript({
+                expression: `testClickEventAttributeHandler("b1", {preventDefault: false})`,
+                eventType: WI.ScriptTimelineRecord.EventType.EventDispatched,
+            });
</ins><span class="cx"> 
</span><span class="cx">             InspectorTest.assert(typeof pageRecordingData.preventDefault === "boolean");
</span><span class="cx"> 
</span><span class="lines">@@ -90,7 +95,10 @@
</span><span class="cx">     suite.addTestCase({
</span><span class="cx">         name: "TimelineEvent.EventDispatch.AttributeHandler.DefaultPrevented",
</span><span class="cx">         async test() {
</span><del>-            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript(`testClickEventAttributeHandler("b2", {preventDefault: true})`);
</del><ins>+            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript({
+                expression: `testClickEventAttributeHandler("b2", {preventDefault: true})`,
+                eventType: WI.ScriptTimelineRecord.EventType.EventDispatched,
+            });
</ins><span class="cx"> 
</span><span class="cx">             InspectorTest.assert(typeof pageRecordingData.preventDefault === "boolean");
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsinspectortimelinetimelineeventFireAnimationFrameexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/timeline/timeline-event-FireAnimationFrame-expected.txt (243404 => 243405)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/timeline/timeline-event-FireAnimationFrame-expected.txt      2019-03-22 22:54:50 UTC (rev 243404)
+++ trunk/LayoutTests/inspector/timeline/timeline-event-FireAnimationFrame-expected.txt 2019-03-22 23:34:29 UTC (rev 243405)
</span><span class="lines">@@ -6,7 +6,6 @@
</span><span class="cx"> Starting Capture...
</span><span class="cx"> Evaluating...
</span><span class="cx"> PASS: requestAnimationFrame fired
</span><del>-Finish recording...
</del><span class="cx"> Stopping Capture...
</span><span class="cx"> PASS: Should be 1 AnimationFrameFired record.
</span><span class="cx"> DETAILS: number
</span></span></pre></div>
<a id="trunkLayoutTestsinspectortimelinetimelineeventFireAnimationFramehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/timeline/timeline-event-FireAnimationFrame.html (243404 => 243405)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/timeline/timeline-event-FireAnimationFrame.html      2019-03-22 22:54:50 UTC (rev 243404)
+++ trunk/LayoutTests/inspector/timeline/timeline-event-FireAnimationFrame.html 2019-03-22 23:34:29 UTC (rev 243405)
</span><span class="lines">@@ -8,11 +8,9 @@
</span><span class="cx"> function testRequestAnimationFrame() {
</span><span class="cx">     let requestAnimationFrameIdentifier = requestAnimationFrame(() => {
</span><span class="cx">         TestPage.addResult("PASS: requestAnimationFrame fired");
</span><ins>+    });
</ins><span class="cx"> 
</span><del>-        setTimeout(() => {
-            finishRecording({requestAnimationFrameIdentifier});
-        });
-    });
</del><ins>+    savePageData({requestAnimationFrameIdentifier});
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function test()
</span><span class="lines">@@ -22,7 +20,10 @@
</span><span class="cx">     suite.addTestCase({
</span><span class="cx">         name: "TimelineEvent.FireAnimationFrame.requestAnimationFrame",
</span><span class="cx">         async test() {
</span><del>-            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript(`testRequestAnimationFrame()`);
</del><ins>+            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript({
+                expression: `testRequestAnimationFrame()`,
+                eventType: WI.ScriptTimelineRecord.EventType.AnimationFrameFired,
+            });
</ins><span class="cx"> 
</span><span class="cx">             InspectorTest.assert(typeof pageRecordingData.requestAnimationFrameIdentifier === "number");
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsinspectortimelinetimelineeventRequestAnimationFrameexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/timeline/timeline-event-RequestAnimationFrame-expected.txt (243404 => 243405)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/timeline/timeline-event-RequestAnimationFrame-expected.txt   2019-03-22 22:54:50 UTC (rev 243404)
+++ trunk/LayoutTests/inspector/timeline/timeline-event-RequestAnimationFrame-expected.txt      2019-03-22 23:34:29 UTC (rev 243405)
</span><span class="lines">@@ -6,7 +6,6 @@
</span><span class="cx"> Starting Capture...
</span><span class="cx"> Evaluating...
</span><span class="cx"> PASS: requestAnimationFrame fired
</span><del>-Finish recording...
</del><span class="cx"> Stopping Capture...
</span><span class="cx"> PASS: Should be 1 AnimationFrameRequested record.
</span><span class="cx"> DETAILS: number
</span></span></pre></div>
<a id="trunkLayoutTestsinspectortimelinetimelineeventRequestAnimationFramehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/timeline/timeline-event-RequestAnimationFrame.html (243404 => 243405)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/timeline/timeline-event-RequestAnimationFrame.html   2019-03-22 22:54:50 UTC (rev 243404)
+++ trunk/LayoutTests/inspector/timeline/timeline-event-RequestAnimationFrame.html      2019-03-22 23:34:29 UTC (rev 243405)
</span><span class="lines">@@ -8,11 +8,9 @@
</span><span class="cx"> function testRequestAnimationFrame() {
</span><span class="cx">     let requestAnimationFrameIdentifier = requestAnimationFrame(() => {
</span><span class="cx">         TestPage.addResult("PASS: requestAnimationFrame fired");
</span><ins>+    });
</ins><span class="cx"> 
</span><del>-        setTimeout(() => {
-            finishRecording({requestAnimationFrameIdentifier});
-        });
-    });
</del><ins>+    savePageData({requestAnimationFrameIdentifier});
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function test()
</span><span class="lines">@@ -22,7 +20,10 @@
</span><span class="cx">     suite.addTestCase({
</span><span class="cx">         name: "TimelineEvent.RequestAnimationFrame.requestAnimationFrame",
</span><span class="cx">         async test() {
</span><del>-            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript(`testRequestAnimationFrame()`);
</del><ins>+            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript({
+                expression: `testRequestAnimationFrame()`,
+                eventType: WI.ScriptTimelineRecord.EventType.AnimationFrameFired,
+            });
</ins><span class="cx"> 
</span><span class="cx">             InspectorTest.assert(typeof pageRecordingData.requestAnimationFrameIdentifier === "number");
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsinspectortimelinetimelineeventTimerFireexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/timeline/timeline-event-TimerFire-expected.txt (243404 => 243405)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/timeline/timeline-event-TimerFire-expected.txt       2019-03-22 22:54:50 UTC (rev 243404)
+++ trunk/LayoutTests/inspector/timeline/timeline-event-TimerFire-expected.txt  2019-03-22 23:34:29 UTC (rev 243405)
</span><span class="lines">@@ -6,7 +6,6 @@
</span><span class="cx"> Starting Capture...
</span><span class="cx"> Evaluating...
</span><span class="cx"> PASS: setTimeout fired
</span><del>-Finish recording...
</del><span class="cx"> Stopping Capture...
</span><span class="cx"> PASS: Should be 1 TimerFired record.
</span><span class="cx"> DETAILS: number
</span><span class="lines">@@ -18,7 +17,6 @@
</span><span class="cx"> PASS: setInterval fired: 1
</span><span class="cx"> PASS: setInterval fired: 2
</span><span class="cx"> PASS: setInterval fired: 3
</span><del>-Finish recording...
</del><span class="cx"> Stopping Capture...
</span><span class="cx"> PASS: Should be 3 TimerFired records.
</span><span class="cx"> DETAILS: number
</span></span></pre></div>
<a id="trunkLayoutTestsinspectortimelinetimelineeventTimerFirehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/timeline/timeline-event-TimerFire.html (243404 => 243405)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/timeline/timeline-event-TimerFire.html       2019-03-22 22:54:50 UTC (rev 243404)
+++ trunk/LayoutTests/inspector/timeline/timeline-event-TimerFire.html  2019-03-22 23:34:29 UTC (rev 243405)
</span><span class="lines">@@ -8,11 +8,9 @@
</span><span class="cx"> function testSetTimeout() {
</span><span class="cx">     let setTimeoutIdentifier = setTimeout(() => {
</span><span class="cx">         TestPage.addResult("PASS: setTimeout fired");
</span><ins>+    }, 10);
</ins><span class="cx"> 
</span><del>-        requestAnimationFrame(() => {
-            finishRecording({setTimeoutIdentifier});
-        });
-    });
</del><ins>+    savePageData({setTimeoutIdentifier});
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function testSetInterval() {
</span><span class="lines">@@ -23,14 +21,11 @@
</span><span class="cx"> 
</span><span class="cx">         TestPage.addResult("PASS: setInterval fired: " + count);
</span><span class="cx"> 
</span><del>-        if (count === 3) {
</del><ins>+        if (count === 3)
</ins><span class="cx">             clearInterval(setIntervalIdentifier);
</span><ins>+    }, 5);
</ins><span class="cx"> 
</span><del>-            requestAnimationFrame(() => {
-                finishRecording({setIntervalIdentifier});
-            });
-        }
-    });
</del><ins>+    savePageData({setIntervalIdentifier});
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function test()
</span><span class="lines">@@ -43,7 +38,10 @@
</span><span class="cx">     suite.addTestCase({
</span><span class="cx">         name: "TimelineEvent.TimerFire.setTimeout",
</span><span class="cx">         async test() {
</span><del>-            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript(`testSetTimeout()`);
</del><ins>+            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript({
+                expression: `testSetTimeout()`,
+                eventType: WI.ScriptTimelineRecord.EventType.TimerFired,
+            });
</ins><span class="cx"> 
</span><span class="cx">             InspectorTest.assert(typeof pageRecordingData.setTimeoutIdentifier === "number");
</span><span class="cx">             timeoutIdentifier = pageRecordingData.setTimeoutIdentifier;
</span><span class="lines">@@ -62,7 +60,10 @@
</span><span class="cx">     suite.addTestCase({
</span><span class="cx">         name: "TimelineEvent.TimerFire.setInterval",
</span><span class="cx">         async test() {
</span><del>-            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript(`testSetInterval()`);
</del><ins>+            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript({
+                expression: `testSetInterval()`,
+                eventType: WI.ScriptTimelineRecord.EventType.TimerRemoved,
+            });
</ins><span class="cx"> 
</span><span class="cx">             InspectorTest.assert(typeof pageRecordingData.setIntervalIdentifier === "number");
</span><span class="cx">             intervalIdentifier = pageRecordingData.setIntervalIdentifier;
</span></span></pre></div>
<a id="trunkLayoutTestsinspectortimelinetimelineeventTimerInstallexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/timeline/timeline-event-TimerInstall-expected.txt (243404 => 243405)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/timeline/timeline-event-TimerInstall-expected.txt    2019-03-22 22:54:50 UTC (rev 243404)
+++ trunk/LayoutTests/inspector/timeline/timeline-event-TimerInstall-expected.txt       2019-03-22 23:34:29 UTC (rev 243405)
</span><span class="lines">@@ -6,7 +6,6 @@
</span><span class="cx"> Starting Capture...
</span><span class="cx"> Evaluating...
</span><span class="cx"> PASS: setTimeout fired
</span><del>-Finish recording...
</del><span class="cx"> Stopping Capture...
</span><span class="cx"> PASS: Should be 1 TimerInstalled record.
</span><span class="cx"> DETAILS: {"timerId":"<filtered>","timeout":10,"repeating":false}
</span><span class="lines">@@ -18,7 +17,6 @@
</span><span class="cx"> PASS: setInterval fired: 1
</span><span class="cx"> PASS: setInterval fired: 2
</span><span class="cx"> PASS: setInterval fired: 3
</span><del>-Finish recording...
</del><span class="cx"> Stopping Capture...
</span><span class="cx"> PASS: Should be 1 TimerInstalled record.
</span><span class="cx"> DETAILS: {"timerId":"<filtered>","timeout":5,"repeating":true}
</span></span></pre></div>
<a id="trunkLayoutTestsinspectortimelinetimelineeventTimerInstallhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/timeline/timeline-event-TimerInstall.html (243404 => 243405)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/timeline/timeline-event-TimerInstall.html    2019-03-22 22:54:50 UTC (rev 243404)
+++ trunk/LayoutTests/inspector/timeline/timeline-event-TimerInstall.html       2019-03-22 23:34:29 UTC (rev 243405)
</span><span class="lines">@@ -8,11 +8,9 @@
</span><span class="cx"> function testSetTimeout() {
</span><span class="cx">     let setTimeoutIdentifier = setTimeout(() => {
</span><span class="cx">         TestPage.addResult("PASS: setTimeout fired");
</span><ins>+    }, 10);
</ins><span class="cx"> 
</span><del>-        requestAnimationFrame(() => {
-            finishRecording({setTimeoutIdentifier});
-        });
-    }, 10);
</del><ins>+    savePageData({setTimeoutIdentifier});
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function testSetInterval() {
</span><span class="lines">@@ -23,14 +21,11 @@
</span><span class="cx"> 
</span><span class="cx">         TestPage.addResult("PASS: setInterval fired: " + count);
</span><span class="cx"> 
</span><del>-        if (count === 3) {
</del><ins>+        if (count === 3)
</ins><span class="cx">             clearInterval(setIntervalIdentifier);
</span><ins>+    }, 5);
</ins><span class="cx"> 
</span><del>-            requestAnimationFrame(() => {
-                finishRecording({setIntervalIdentifier});
-            });
-        }
-    }, 5);
</del><ins>+    savePageData({setIntervalIdentifier});
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function test()
</span><span class="lines">@@ -49,7 +44,10 @@
</span><span class="cx">     suite.addTestCase({
</span><span class="cx">         name: "TimelineEvent.TimerInstall.setTimeout",
</span><span class="cx">         async test() {
</span><del>-            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript(`testSetTimeout()`);
</del><ins>+            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript({
+                expression: `testSetTimeout()`,
+                eventType: WI.ScriptTimelineRecord.EventType.TimerFired,
+            });
</ins><span class="cx"> 
</span><span class="cx">             InspectorTest.assert(typeof pageRecordingData.setTimeoutIdentifier === "number");
</span><span class="cx">             timeoutIdentifier = pageRecordingData.setTimeoutIdentifier;
</span><span class="lines">@@ -68,7 +66,10 @@
</span><span class="cx">     suite.addTestCase({
</span><span class="cx">         name: "TimelineEvent.TimerInstall.setInterval",
</span><span class="cx">         async test() {
</span><del>-            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript(`testSetInterval()`);
</del><ins>+            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript({
+                expression: `testSetInterval()`,
+                eventType: WI.ScriptTimelineRecord.EventType.TimerRemoved,
+            });
</ins><span class="cx"> 
</span><span class="cx">             InspectorTest.assert(typeof pageRecordingData.setIntervalIdentifier === "number");
</span><span class="cx">             intervalIdentifier = pageRecordingData.setIntervalIdentifier;
</span></span></pre></div>
<a id="trunkLayoutTestsinspectortimelinetimelineeventTimerRemoveexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/timeline/timeline-event-TimerRemove-expected.txt (243404 => 243405)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/timeline/timeline-event-TimerRemove-expected.txt     2019-03-22 22:54:50 UTC (rev 243404)
+++ trunk/LayoutTests/inspector/timeline/timeline-event-TimerRemove-expected.txt        2019-03-22 23:34:29 UTC (rev 243405)
</span><span class="lines">@@ -5,7 +5,6 @@
</span><span class="cx"> -- Running test case: TimelineEvent.TimerRemove.setTimeout
</span><span class="cx"> Starting Capture...
</span><span class="cx"> Evaluating...
</span><del>-Finish recording...
</del><span class="cx"> Stopping Capture...
</span><span class="cx"> PASS: Should be 1 TimerRemoved record.
</span><span class="cx"> DETAILS: number
</span><span class="lines">@@ -17,7 +16,6 @@
</span><span class="cx"> PASS: setInterval fired: 1
</span><span class="cx"> PASS: setInterval fired: 2
</span><span class="cx"> PASS: setInterval fired: 3
</span><del>-Finish recording...
</del><span class="cx"> Stopping Capture...
</span><span class="cx"> PASS: Should be 1 TimerRemoved record.
</span><span class="cx"> DETAILS: number
</span></span></pre></div>
<a id="trunkLayoutTestsinspectortimelinetimelineeventTimerRemovehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/timeline/timeline-event-TimerRemove.html (243404 => 243405)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/timeline/timeline-event-TimerRemove.html     2019-03-22 22:54:50 UTC (rev 243404)
+++ trunk/LayoutTests/inspector/timeline/timeline-event-TimerRemove.html        2019-03-22 23:34:29 UTC (rev 243405)
</span><span class="lines">@@ -8,13 +8,11 @@
</span><span class="cx"> function testSetTimeout() {
</span><span class="cx">     let setTimeoutIdentifier = setTimeout(() => {
</span><span class="cx">         TestPage.addResult("FAIL: setTimeout fired");
</span><del>-    });
</del><ins>+    }, 10);
</ins><span class="cx"> 
</span><ins>+    savePageData({setTimeoutIdentifier});
+
</ins><span class="cx">     clearTimeout(setTimeoutIdentifier);
</span><del>-
-    requestAnimationFrame(() => {
-        finishRecording({setTimeoutIdentifier});
-    });
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function testSetInterval() {
</span><span class="lines">@@ -25,14 +23,11 @@
</span><span class="cx"> 
</span><span class="cx">         TestPage.addResult("PASS: setInterval fired: " + count);
</span><span class="cx"> 
</span><del>-        if (count === 3) {
</del><ins>+        if (count === 3)
</ins><span class="cx">             clearInterval(setIntervalIdentifier);
</span><ins>+    }, 5);
</ins><span class="cx"> 
</span><del>-            requestAnimationFrame(() => {
-                finishRecording({setIntervalIdentifier});
-            });
-        }
-    });
</del><ins>+    savePageData({setIntervalIdentifier});
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function test()
</span><span class="lines">@@ -45,7 +40,10 @@
</span><span class="cx">     suite.addTestCase({
</span><span class="cx">         name: "TimelineEvent.TimerRemove.setTimeout",
</span><span class="cx">         async test() {
</span><del>-            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript(`testSetTimeout()`);
</del><ins>+            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript({
+                expression: `testSetTimeout()`,
+                eventType: WI.ScriptTimelineRecord.EventType.TimerRemoved,
+            });
</ins><span class="cx"> 
</span><span class="cx">             InspectorTest.assert(typeof pageRecordingData.setTimeoutIdentifier === "number");
</span><span class="cx">             timeoutIdentifier = pageRecordingData.setTimeoutIdentifier;
</span><span class="lines">@@ -64,7 +62,10 @@
</span><span class="cx">     suite.addTestCase({
</span><span class="cx">         name: "TimelineEvent.TimerRemove.setInterval",
</span><span class="cx">         async test() {
</span><del>-            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript(`testSetInterval()`);
</del><ins>+            let pageRecordingData = await InspectorTest.TimelineEvent.captureTimelineWithScript({
+                expression: `testSetInterval()`,
+                eventType: WI.ScriptTimelineRecord.EventType.TimerRemoved,
+            });
</ins><span class="cx"> 
</span><span class="cx">             InspectorTest.assert(typeof pageRecordingData.setIntervalIdentifier === "number");
</span><span class="cx">             intervalIdentifier = pageRecordingData.setIntervalIdentifier;
</span></span></pre>
</div>
</div>

</body>
</html>