2 * Copyright (C) 2017 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
28 #if ENABLE(DATA_INTERACTION)
30 #import "DataInteractionSimulator.h"
31 #import "PlatformUtilities.h"
32 #import "TestWKWebView.h"
33 #import "WKWebViewConfigurationExtras.h"
34 #import <MobileCoreServices/MobileCoreServices.h>
35 #import <UIKit/NSString+UIItemProvider.h>
36 #import <UIKit/NSURL+UIItemProvider.h>
37 #import <UIKit/UIImage+UIItemProvider.h>
38 #import <UIKit/UIItemProvider_Private.h>
39 #import <WebKit/WKPreferencesPrivate.h>
40 #import <WebKit/WKProcessPoolPrivate.h>
41 #import <WebKit/WKWebViewConfigurationPrivate.h>
42 #import <WebKit/WebItemProviderPasteboard.h>
43 #import <WebKit/_WKProcessPoolConfiguration.h>
45 typedef void (^FileLoadCompletionBlock)(NSURL *, BOOL, NSError *);
46 typedef void (^DataLoadCompletionBlock)(NSData *, NSError *);
48 static NSString *InjectedBundlePasteboardDataType = @"org.webkit.data";
50 static UIImage *testIconImage()
52 return [UIImage imageNamed:@"TestWebKitAPI.resources/icon.png"];
55 static NSData *testZIPArchive()
57 NSURL *zipFileURL = [[NSBundle mainBundle] URLForResource:@"compressed-files" withExtension:@"zip" subdirectory:@"TestWebKitAPI.resources"];
58 return [NSData dataWithContentsOfURL:zipFileURL];
61 @implementation UIItemProvider (DataInteractionTests)
63 - (void)registerDataRepresentationForTypeIdentifier:(NSString *)typeIdentifier withData:(NSData *)data
65 RetainPtr<NSData> retainedData = data;
66 [self registerDataRepresentationForTypeIdentifier:typeIdentifier visibility:UIItemProviderRepresentationOptionsVisibilityAll loadHandler: [retainedData] (DataLoadCompletionBlock block) -> NSProgress * {
67 block(retainedData.get(), nil);
68 return [NSProgress discreteProgressWithTotalUnitCount:100];
74 @implementation TestWKWebView (DataInteractionTests)
76 - (BOOL)editorContainsImageElement
78 return [self stringByEvaluatingJavaScript:@"!!editor.querySelector('img')"].boolValue;
81 - (NSString *)editorValue
83 return [self stringByEvaluatingJavaScript:@"editor.value"];
88 static NSValue *makeCGRectValue(CGFloat x, CGFloat y, CGFloat width, CGFloat height)
90 return [NSValue valueWithCGRect:CGRectMake(x, y, width, height)];
93 static void checkSelectionRectsWithLogging(NSArray *expected, NSArray *observed)
95 if (![expected isEqualToArray:observed])
96 NSLog(@"Expected selection rects: %@ but observed: %@", expected, observed);
97 EXPECT_TRUE([expected isEqualToArray:observed]);
100 static void checkTypeIdentifierPrecedesOtherTypeIdentifier(DataInteractionSimulator *simulator, NSString *firstType, NSString *secondType)
102 NSArray *registeredTypes = [simulator.sourceItemProviders.firstObject registeredTypeIdentifiers];
103 EXPECT_TRUE([registeredTypes containsObject:firstType]);
104 EXPECT_TRUE([registeredTypes containsObject:secondType]);
105 EXPECT_TRUE([registeredTypes indexOfObject:firstType] < [registeredTypes indexOfObject:secondType]);
108 static void checkTypeIdentifierIsRegisteredAtIndex(DataInteractionSimulator *simulator, NSString *type, NSUInteger index)
110 NSArray *registeredTypes = [simulator.sourceItemProviders.firstObject registeredTypeIdentifiers];
111 EXPECT_GT(registeredTypes.count, index);
112 EXPECT_WK_STREQ(type.UTF8String, [registeredTypes[index] UTF8String]);
115 static void checkSuggestedNameAndEstimatedSize(DataInteractionSimulator *simulator, NSString *suggestedName, CGSize estimatedSize)
117 UIItemProvider *sourceItemProvider = [simulator sourceItemProviders].firstObject;
118 EXPECT_WK_STREQ(suggestedName.UTF8String, sourceItemProvider.suggestedName.UTF8String);
119 EXPECT_EQ(estimatedSize.width, sourceItemProvider.estimatedDisplayedSize.width);
120 EXPECT_EQ(estimatedSize.height, sourceItemProvider.estimatedDisplayedSize.height);
123 static void checkStringArraysAreEqual(NSArray<NSString *> *expected, NSArray<NSString *> *observed)
125 EXPECT_EQ(expected.count, observed.count);
126 for (NSUInteger index = 0; index < expected.count; ++index) {
127 NSString *expectedString = [expected objectAtIndex:index];
128 NSString *observedString = [observed objectAtIndex:index];
129 EXPECT_WK_STREQ(expectedString, observedString);
130 if (![expectedString isEqualToString:observedString])
131 NSLog(@"Expected observed string: %@ to match expected string: %@ at index: %tu", observedString, expectedString, index);
135 static void checkDragCaretRectIsContainedInRect(CGRect caretRect, CGRect containerRect)
137 BOOL contained = CGRectContainsRect(containerRect, caretRect);
138 EXPECT_TRUE(contained);
140 NSLog(@"Expected caret rect: %@ to fit within container rect: %@", NSStringFromCGRect(caretRect), NSStringFromCGRect(containerRect));
143 namespace TestWebKitAPI {
145 TEST(DataInteractionTests, ImageToContentEditable)
147 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
148 [webView synchronouslyLoadTestPageNamed:@"image-and-contenteditable"];
150 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
151 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
153 EXPECT_TRUE([webView editorContainsImageElement]);
155 NSArray *observedEventNames = [dataInteractionSimulator observedEventNames];
156 EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]);
157 EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]);
158 EXPECT_TRUE([observedEventNames containsObject:DataInteractionPerformOperationEventName]);
159 checkSelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 215, 174) ], [dataInteractionSimulator finalSelectionRects]);
160 checkTypeIdentifierPrecedesOtherTypeIdentifier(dataInteractionSimulator.get(), (NSString *)kUTTypePNG, (NSString *)kUTTypeFileURL);
161 checkSuggestedNameAndEstimatedSize(dataInteractionSimulator.get(), @"icon.png", { 215, 174 });
164 TEST(DataInteractionTests, ImageToTextarea)
166 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
167 [webView synchronouslyLoadTestPageNamed:@"image-and-textarea"];
169 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
170 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
172 NSURL *imageURL = [NSURL fileURLWithPath:[webView editorValue]];
173 EXPECT_WK_STREQ("icon.png", imageURL.lastPathComponent);
175 NSArray *observedEventNames = [dataInteractionSimulator observedEventNames];
176 EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]);
177 EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]);
178 EXPECT_TRUE([observedEventNames containsObject:DataInteractionPerformOperationEventName]);
180 checkTypeIdentifierPrecedesOtherTypeIdentifier(dataInteractionSimulator.get(), (NSString *)kUTTypePNG, (NSString *)kUTTypeFileURL);
181 checkSuggestedNameAndEstimatedSize(dataInteractionSimulator.get(), @"icon.png", { 215, 174 });
184 TEST(DataInteractionTests, ImageInLinkToInput)
186 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
187 [webView synchronouslyLoadTestPageNamed:@"image-in-link-and-input"];
189 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
190 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
192 EXPECT_WK_STREQ("https://www.apple.com/", [webView editorValue].UTF8String);
193 checkSelectionRectsWithLogging(@[ makeCGRectValue(101, 241, 2057, 232) ], [dataInteractionSimulator finalSelectionRects]);
194 checkSuggestedNameAndEstimatedSize(dataInteractionSimulator.get(), @"icon.png", { 215, 174 });
195 checkTypeIdentifierIsRegisteredAtIndex(dataInteractionSimulator.get(), (NSString *)kUTTypePNG, 0);
198 TEST(DataInteractionTests, ImageInLinkWithoutHREFToInput)
200 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
201 [webView synchronouslyLoadTestPageNamed:@"image-in-link-and-input"];
202 [webView stringByEvaluatingJavaScript:@"link.href = ''"];
204 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
205 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
207 NSURL *imageURL = [NSURL fileURLWithPath:[webView editorValue]];
208 EXPECT_WK_STREQ("icon.png", imageURL.lastPathComponent);
209 checkSuggestedNameAndEstimatedSize(dataInteractionSimulator.get(), @"icon.png", { 215, 174 });
210 checkTypeIdentifierIsRegisteredAtIndex(dataInteractionSimulator.get(), (NSString *)kUTTypePNG, 0);
213 TEST(DataInteractionTests, ImageDoesNotUseElementSizeAsEstimatedSize)
215 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
216 [webView synchronouslyLoadTestPageNamed:@"gif-and-file-input"];
218 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
219 [dataInteractionSimulator runFrom: { 100, 100 } to: { 100, 300 }];
221 checkTypeIdentifierIsRegisteredAtIndex(dataInteractionSimulator.get(), (NSString *)kUTTypeGIF, 0);
222 checkSuggestedNameAndEstimatedSize(dataInteractionSimulator.get(), @"apple.gif", { 52, 64 });
223 EXPECT_WK_STREQ("apple.gif (image/gif)", [webView stringByEvaluatingJavaScript:@"output.textContent"]);
226 TEST(DataInteractionTests, ContentEditableToContentEditable)
228 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
229 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
231 [webView loadTestPageNamed:@"autofocus-contenteditable"];
232 [dataInteractionSimulator waitForInputSession];
233 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
235 EXPECT_EQ([webView stringByEvaluatingJavaScript:@"source.textContent"].length, 0UL);
236 EXPECT_WK_STREQ("Hello world", [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String);
238 NSArray *observedEventNames = [dataInteractionSimulator observedEventNames];
239 EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]);
240 EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]);
241 EXPECT_TRUE([observedEventNames containsObject:DataInteractionPerformOperationEventName]);
242 checkSelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 961, 227) ], [dataInteractionSimulator finalSelectionRects]);
243 checkTypeIdentifierPrecedesOtherTypeIdentifier(dataInteractionSimulator.get(), (NSString *)kUTTypeRTFD, (NSString *)kUTTypeUTF8PlainText);
246 TEST(DataInteractionTests, ContentEditableToTextarea)
248 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
249 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
251 [webView loadTestPageNamed:@"contenteditable-and-textarea"];
252 [dataInteractionSimulator waitForInputSession];
253 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
255 EXPECT_EQ([webView stringByEvaluatingJavaScript:@"source.textContent"].length, 0UL);
256 EXPECT_WK_STREQ("Hello world", [webView editorValue].UTF8String);
258 NSArray *observedEventNames = [dataInteractionSimulator observedEventNames];
259 EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]);
260 EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]);
261 EXPECT_TRUE([observedEventNames containsObject:DataInteractionPerformOperationEventName]);
262 checkSelectionRectsWithLogging(@[ makeCGRectValue(6, 203, 990, 232) ], [dataInteractionSimulator finalSelectionRects]);
263 checkTypeIdentifierPrecedesOtherTypeIdentifier(dataInteractionSimulator.get(), (NSString *)kUTTypeRTFD, (NSString *)kUTTypeUTF8PlainText);
266 TEST(DataInteractionTests, ContentEditableMoveParagraphs)
268 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
269 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
271 [webView loadTestPageNamed:@"two-paragraph-contenteditable"];
272 [dataInteractionSimulator waitForInputSession];
273 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(250, 450)];
275 NSString *finalTextContent = [webView stringByEvaluatingJavaScript:@"editor.textContent"];
276 NSUInteger firstParagraphOffset = [finalTextContent rangeOfString:@"This is the first paragraph"].location;
277 NSUInteger secondParagraphOffset = [finalTextContent rangeOfString:@"This is the second paragraph"].location;
279 EXPECT_FALSE(firstParagraphOffset == NSNotFound);
280 EXPECT_FALSE(secondParagraphOffset == NSNotFound);
281 EXPECT_GT(firstParagraphOffset, secondParagraphOffset);
282 checkSelectionRectsWithLogging(@[ makeCGRectValue(190, 100, 130, 20), makeCGRectValue(0, 120, 320, 100), makeCGRectValue(0, 220, 252, 20) ], [dataInteractionSimulator finalSelectionRects]);
285 TEST(DataInteractionTests, DragImageFromContentEditable)
287 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
288 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
290 [webView synchronouslyLoadTestPageNamed:@"contenteditable-and-target"];
291 [dataInteractionSimulator runFrom:CGPointMake(100, 100) to:CGPointMake(100, 300)];
293 EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target.textContent"]);
296 TEST(DataInteractionTests, TextAreaToInput)
298 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
299 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
301 [webView loadTestPageNamed:@"textarea-to-input"];
302 [dataInteractionSimulator waitForInputSession];
303 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
305 EXPECT_EQ([webView stringByEvaluatingJavaScript:@"source.value"].length, 0UL);
306 EXPECT_WK_STREQ("Hello world", [webView editorValue].UTF8String);
307 checkSelectionRectsWithLogging(@[ makeCGRectValue(101, 241, 990, 232) ], [dataInteractionSimulator finalSelectionRects]);
310 TEST(DataInteractionTests, SinglePlainTextWordTypeIdentifiers)
312 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
313 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
315 [webView loadTestPageNamed:@"textarea-to-input"];
316 [dataInteractionSimulator waitForInputSession];
317 [webView stringByEvaluatingJavaScript:@"source.value = 'pneumonoultramicroscopicsilicovolcanoconiosis'"];
318 [webView stringByEvaluatingJavaScript:@"source.selectionStart = 0"];
319 [webView stringByEvaluatingJavaScript:@"source.selectionEnd = source.value.length"];
320 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
322 NSArray *registeredTypes = [[dataInteractionSimulator sourceItemProviders].firstObject registeredTypeIdentifiers];
323 EXPECT_EQ(1UL, registeredTypes.count);
324 EXPECT_WK_STREQ([(NSString *)kUTTypeUTF8PlainText UTF8String], [registeredTypes.firstObject UTF8String]);
325 EXPECT_EQ([webView stringByEvaluatingJavaScript:@"source.value"].length, 0UL);
326 EXPECT_WK_STREQ("pneumonoultramicroscopicsilicovolcanoconiosis", [webView editorValue].UTF8String);
329 TEST(DataInteractionTests, SinglePlainTextURLTypeIdentifiers)
331 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
332 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
334 [webView loadTestPageNamed:@"textarea-to-input"];
335 [dataInteractionSimulator waitForInputSession];
336 [webView stringByEvaluatingJavaScript:@"source.value = 'https://webkit.org/'"];
337 [webView stringByEvaluatingJavaScript:@"source.selectionStart = 0"];
338 [webView stringByEvaluatingJavaScript:@"source.selectionEnd = source.value.length"];
339 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
341 NSArray *registeredTypes = [[dataInteractionSimulator sourceItemProviders].firstObject registeredTypeIdentifiers];
342 EXPECT_EQ(2UL, registeredTypes.count);
343 EXPECT_WK_STREQ([(NSString *)kUTTypeURL UTF8String], [registeredTypes.firstObject UTF8String]);
344 EXPECT_WK_STREQ([(NSString *)kUTTypeUTF8PlainText UTF8String], [registeredTypes.lastObject UTF8String]);
345 EXPECT_EQ(0UL, [webView stringByEvaluatingJavaScript:@"source.value"].length);
346 EXPECT_WK_STREQ("https://webkit.org/", [webView editorValue].UTF8String);
349 TEST(DataInteractionTests, LinkToInput)
351 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
352 [webView synchronouslyLoadTestPageNamed:@"link-and-input"];
354 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
355 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
357 EXPECT_WK_STREQ("https://www.apple.com/", [webView editorValue].UTF8String);
359 __block bool doneLoadingURL = false;
360 UIItemProvider *sourceItemProvider = [dataInteractionSimulator sourceItemProviders].firstObject;
361 [sourceItemProvider loadObjectOfClass:[NSURL class] completionHandler:^(id object, NSError *error) {
363 EXPECT_WK_STREQ("Hello world", url._title.UTF8String ?: "");
364 doneLoadingURL = true;
366 TestWebKitAPI::Util::run(&doneLoadingURL);
368 NSArray *observedEventNames = [dataInteractionSimulator observedEventNames];
369 EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]);
370 EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]);
371 EXPECT_TRUE([observedEventNames containsObject:DataInteractionPerformOperationEventName]);
372 checkSelectionRectsWithLogging(@[ makeCGRectValue(101, 273, 2057, 232) ], [dataInteractionSimulator finalSelectionRects]);
373 checkTypeIdentifierIsRegisteredAtIndex(dataInteractionSimulator.get(), (NSString *)kUTTypeURL, 0);
376 TEST(DataInteractionTests, BackgroundImageLinkToInput)
378 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
379 [webView synchronouslyLoadTestPageNamed:@"background-image-link-and-input"];
381 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
382 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
384 EXPECT_WK_STREQ("https://www.apple.com/", [webView editorValue].UTF8String);
386 NSArray *observedEventNames = [dataInteractionSimulator observedEventNames];
387 EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]);
388 EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]);
389 EXPECT_TRUE([observedEventNames containsObject:DataInteractionPerformOperationEventName]);
390 checkSelectionRectsWithLogging(@[ makeCGRectValue(101, 241, 2057, 232) ], [dataInteractionSimulator finalSelectionRects]);
391 checkTypeIdentifierIsRegisteredAtIndex(dataInteractionSimulator.get(), (NSString *)kUTTypeURL, 0);
394 TEST(DataInteractionTests, CanPreventStart)
396 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
397 [webView synchronouslyLoadTestPageNamed:@"prevent-start"];
399 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
400 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
402 EXPECT_EQ(DataInteractionCancelled, [dataInteractionSimulator phase]);
403 EXPECT_FALSE([webView editorContainsImageElement]);
405 NSArray *observedEventNames = [dataInteractionSimulator observedEventNames];
406 EXPECT_FALSE([observedEventNames containsObject:DataInteractionEnterEventName]);
407 EXPECT_FALSE([observedEventNames containsObject:DataInteractionOverEventName]);
408 checkSelectionRectsWithLogging(@[ ], [dataInteractionSimulator finalSelectionRects]);
411 TEST(DataInteractionTests, CanPreventOperation)
413 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
414 [webView synchronouslyLoadTestPageNamed:@"prevent-operation"];
416 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
417 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
419 EXPECT_FALSE([webView editorContainsImageElement]);
421 NSArray *observedEventNames = [dataInteractionSimulator observedEventNames];
422 EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]);
423 EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]);
424 checkSelectionRectsWithLogging(@[ ], [dataInteractionSimulator finalSelectionRects]);
427 TEST(DataInteractionTests, EnterAndLeaveEvents)
429 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
430 [webView synchronouslyLoadTestPageNamed:@"link-and-input"];
432 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
433 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 450)];
435 EXPECT_WK_STREQ("", [webView editorValue].UTF8String);
437 NSArray *observedEventNames = [dataInteractionSimulator observedEventNames];
438 EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]);
439 EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]);
440 EXPECT_TRUE([observedEventNames containsObject:DataInteractionLeaveEventName]);
441 EXPECT_FALSE([observedEventNames containsObject:DataInteractionPerformOperationEventName]);
442 checkSelectionRectsWithLogging(@[ ], [dataInteractionSimulator finalSelectionRects]);
445 TEST(DataInteractionTests, ExternalSourcePlainTextToIFrame)
447 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
448 [webView synchronouslyLoadTestPageNamed:@"contenteditable-in-iframe"];
450 auto itemProvider = adoptNS([[UIItemProvider alloc] init]);
451 [itemProvider registerObject:@"Hello world" visibility:UIItemProviderRepresentationOptionsVisibilityAll];
453 auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
454 [simulator setExternalItemProviders:@[ itemProvider.get() ]];
455 [simulator runFrom:CGPointMake(0, 0) to:CGPointMake(160, 250)];
457 auto containerLeft = [webView stringByEvaluatingJavaScript:@"container.getBoundingClientRect().left"].floatValue;
458 auto containerTop = [webView stringByEvaluatingJavaScript:@"container.getBoundingClientRect().top"].floatValue;
459 auto containerWidth = [webView stringByEvaluatingJavaScript:@"container.getBoundingClientRect().width"].floatValue;
460 auto containerHeight = [webView stringByEvaluatingJavaScript:@"container.getBoundingClientRect().height"].floatValue;
461 checkDragCaretRectIsContainedInRect([simulator lastKnownDragCaretRect], CGRectMake(containerLeft, containerTop, containerWidth, containerHeight));
464 TEST(DataInteractionTests, ExternalSourceJSONToFileInput)
466 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
467 [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
469 RetainPtr<UIItemProvider> simulatedJSONItemProvider = adoptNS([[UIItemProvider alloc] init]);
470 NSData *jsonData = [@"{ \"foo\": \"bar\", \"bar\": \"baz\" }" dataUsingEncoding:NSUTF8StringEncoding];
471 [simulatedJSONItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJSON withData:jsonData];
473 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
474 [dataInteractionSimulator setExternalItemProviders:@[ simulatedJSONItemProvider.get() ]];
475 [dataInteractionSimulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)];
477 EXPECT_WK_STREQ("application/json", [webView stringByEvaluatingJavaScript:@"output.value"]);
480 TEST(DataInteractionTests, ExternalSourceImageToFileInput)
482 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
483 [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
485 RetainPtr<UIItemProvider> simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]);
486 NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5);
487 [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData];
489 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
490 [dataInteractionSimulator setExternalItemProviders:@[ simulatedImageItemProvider.get() ]];
491 [dataInteractionSimulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)];
493 NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"];
494 EXPECT_WK_STREQ("image/jpeg", outputValue.UTF8String);
497 TEST(DataInteractionTests, ExternalSourceHTMLToUploadArea)
499 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
500 [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
502 RetainPtr<UIItemProvider> simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
503 NSData *htmlData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding];
504 [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData];
506 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
507 [dataInteractionSimulator setExternalItemProviders:@[ simulatedHTMLItemProvider.get() ]];
508 [dataInteractionSimulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)];
510 NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"];
511 EXPECT_WK_STREQ("text/html", outputValue.UTF8String);
514 TEST(DataInteractionTests, ExternalSourceZIPArchiveAndURLToSingleFileInput)
516 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
517 [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
519 auto archiveProvider = adoptNS([[UIItemProvider alloc] init]);
520 [archiveProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeZipArchive withData:testZIPArchive()];
522 auto urlProvider = adoptNS([[UIItemProvider alloc] init]);
523 [urlProvider registerObject:[NSURL URLWithString:@"https://webkit.org"] visibility:UIItemProviderRepresentationOptionsVisibilityAll];
525 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
526 [dataInteractionSimulator setExternalItemProviders:@[ archiveProvider.get(), urlProvider.get() ]];
527 [dataInteractionSimulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)];
529 NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"];
530 EXPECT_WK_STREQ("application/zip", outputValue.UTF8String);
533 TEST(DataInteractionTests, ExternalSourceZIPArchiveToUploadArea)
535 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
536 [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
538 auto itemProvider = adoptNS([[UIItemProvider alloc] init]);
539 [itemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeZipArchive withData:testZIPArchive()];
541 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
542 [dataInteractionSimulator setExternalItemProviders:@[ itemProvider.get() ]];
543 [dataInteractionSimulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)];
545 NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"];
546 EXPECT_WK_STREQ("application/zip", outputValue.UTF8String);
549 TEST(DataInteractionTests, ExternalSourceImageAndHTMLToSingleFileInput)
551 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
552 [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
554 RetainPtr<UIItemProvider> simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]);
555 NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5);
556 [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData];
558 RetainPtr<UIItemProvider> simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
559 NSData *htmlData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding];
560 [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData];
562 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
563 [dataInteractionSimulator setExternalItemProviders:@[ simulatedHTMLItemProvider.get(), simulatedImageItemProvider.get() ]];
564 [dataInteractionSimulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)];
566 NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"];
567 EXPECT_WK_STREQ("", outputValue.UTF8String);
570 TEST(DataInteractionTests, ExternalSourceImageAndHTMLToMultipleFileInput)
572 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
573 [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
574 [webView stringByEvaluatingJavaScript:@"input.setAttribute('multiple', '')"];
576 RetainPtr<UIItemProvider> simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]);
577 NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5);
578 [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData];
580 RetainPtr<UIItemProvider> simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
581 NSData *htmlData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding];
582 [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData];
584 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
585 [dataInteractionSimulator setExternalItemProviders:@[ simulatedHTMLItemProvider.get(), simulatedImageItemProvider.get() ]];
586 [dataInteractionSimulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)];
588 NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"];
589 EXPECT_WK_STREQ("image/jpeg, text/html", outputValue.UTF8String);
592 TEST(DataInteractionTests, ExternalSourceImageAndHTMLToUploadArea)
594 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
595 [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
597 RetainPtr<UIItemProvider> simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]);
598 NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5);
599 [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData];
601 RetainPtr<UIItemProvider> firstSimulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
602 NSData *firstHTMLData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding];
603 [firstSimulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:firstHTMLData];
605 RetainPtr<UIItemProvider> secondSimulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
606 NSData *secondHTMLData = [@"<html><body>hello world</body></html>" dataUsingEncoding:NSUTF8StringEncoding];
607 [secondSimulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:secondHTMLData];
609 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
610 [dataInteractionSimulator setExternalItemProviders:@[ simulatedImageItemProvider.get(), firstSimulatedHTMLItemProvider.get(), secondSimulatedHTMLItemProvider.get() ]];
611 [dataInteractionSimulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)];
613 NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"];
614 EXPECT_WK_STREQ("image/jpeg, text/html, text/html", outputValue.UTF8String);
617 TEST(DataInteractionTests, ExternalSourceHTMLToContentEditable)
619 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
620 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
621 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
623 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
624 auto itemProvider = adoptNS([[UIItemProvider alloc] init]);
625 NSData *htmlData = [@"<h1>This is a test</h1>" dataUsingEncoding:NSUTF8StringEncoding];
626 [itemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData];
627 [dataInteractionSimulator setExternalItemProviders:@[ itemProvider.get() ]];
628 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
630 NSString *textContent = [webView stringByEvaluatingJavaScript:@"editor.textContent"];
631 EXPECT_WK_STREQ("This is a test", textContent.UTF8String);
632 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"!!editor.querySelector('h1')"].boolValue);
635 TEST(DataInteractionTests, ExternalSourceAttributedStringToContentEditable)
637 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
638 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
639 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
641 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
642 NSDictionary *textAttributes = @{ NSFontAttributeName: [UIFont boldSystemFontOfSize:20] };
643 NSAttributedString *richText = [[NSAttributedString alloc] initWithString:@"This is a test" attributes:textAttributes];
644 auto itemProvider = adoptNS([[UIItemProvider alloc] initWithObject:richText]);
645 [dataInteractionSimulator setExternalItemProviders:@[ itemProvider.get() ]];
646 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
648 EXPECT_WK_STREQ("This is a test", [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String);
651 TEST(DataInteractionTests, ExternalSourceMultipleURLsToContentEditable)
653 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
654 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
655 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
657 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
658 auto firstItem = adoptNS([[UIItemProvider alloc] init]);
659 [firstItem registerObject:[NSURL URLWithString:@"https://www.apple.com/iphone/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll];
660 auto secondItem = adoptNS([[UIItemProvider alloc] init]);
661 [secondItem registerObject:[NSURL URLWithString:@"https://www.apple.com/mac/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll];
662 auto thirdItem = adoptNS([[UIItemProvider alloc] init]);
663 [thirdItem registerObject:[NSURL URLWithString:@"https://webkit.org/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll];
664 [dataInteractionSimulator setExternalItemProviders:@[ firstItem.get(), secondItem.get(), thirdItem.get() ]];
665 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
667 NSArray *separatedLinks = [[webView stringByEvaluatingJavaScript:@"editor.textContent"] componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
668 EXPECT_EQ(3UL, separatedLinks.count);
669 EXPECT_WK_STREQ("https://www.apple.com/iphone/", separatedLinks[0]);
670 EXPECT_WK_STREQ("https://www.apple.com/mac/", separatedLinks[1]);
671 EXPECT_WK_STREQ("https://webkit.org/", separatedLinks[2]);
674 TEST(DataInteractionTests, RespectsExternalSourceFidelityRankings)
676 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
677 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
678 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
680 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
682 // Here, our source item provider vends two representations: plain text, and then an image. If we don't respect the
683 // fidelity order requested by the source, we'll end up assuming that the image is a higher fidelity representation
684 // than the plain text, and erroneously insert the image. If we respect source fidelities, we'll insert text rather
686 auto simulatedItemProviderWithTextFirst = adoptNS([[UIItemProvider alloc] init]);
687 [simulatedItemProviderWithTextFirst registerObject:@"Hello world" visibility:UIItemProviderRepresentationOptionsVisibilityAll];
688 [simulatedItemProviderWithTextFirst registerObject:testIconImage() visibility:UIItemProviderRepresentationOptionsVisibilityAll];
689 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProviderWithTextFirst.get() ]];
691 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
692 EXPECT_WK_STREQ("Hello world", [webView stringByEvaluatingJavaScript:@"editor.textContent"]);
693 EXPECT_FALSE([webView editorContainsImageElement]);
694 [webView stringByEvaluatingJavaScript:@"editor.innerHTML = ''"];
696 // Now we register the item providers in reverse, and expect the image to be inserted instead of text.
697 auto simulatedItemProviderWithImageFirst = adoptNS([[UIItemProvider alloc] init]);
698 [simulatedItemProviderWithImageFirst registerObject:testIconImage() visibility:UIItemProviderRepresentationOptionsVisibilityAll];
699 [simulatedItemProviderWithImageFirst registerObject:@"Hello world" visibility:UIItemProviderRepresentationOptionsVisibilityAll];
700 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProviderWithImageFirst.get() ]];
702 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
703 EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"editor.textContent"]);
704 EXPECT_TRUE([webView editorContainsImageElement]);
707 TEST(DataInteractionTests, ExternalSourceUTF8PlainTextOnly)
709 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
710 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
712 NSString *textPayload = @"Ceci n'est pas une string";
713 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
714 RetainPtr<UIItemProvider> simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]);
715 [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock)
717 completionBlock([textPayload dataUsingEncoding:NSUTF8StringEncoding], nil);
718 return [NSProgress discreteProgressWithTotalUnitCount:100];
720 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]];
721 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
722 EXPECT_WK_STREQ(textPayload.UTF8String, [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String);
723 checkSelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 1936, 227) ], [dataInteractionSimulator finalSelectionRects]);
726 TEST(DataInteractionTests, ExternalSourceJPEGOnly)
728 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
729 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
731 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
732 RetainPtr<UIItemProvider> simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]);
733 [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypeJPEG options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock)
735 completionBlock(UIImageJPEGRepresentation(testIconImage(), 0.5), nil);
736 return [NSProgress discreteProgressWithTotalUnitCount:100];
738 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]];
739 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
740 EXPECT_TRUE([webView editorContainsImageElement]);
741 checkSelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 215, 174) ], [dataInteractionSimulator finalSelectionRects]);
744 TEST(DataInteractionTests, ExternalSourceTitledNSURL)
746 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
747 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
748 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
750 NSURL *titledURL = [NSURL URLWithString:@"https://www.apple.com"];
751 titledURL._title = @"Apple";
752 auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]);
753 [simulatedItemProvider registerObject:titledURL visibility:UIItemProviderRepresentationOptionsVisibilityAll];
755 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
756 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]];
757 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
759 EXPECT_WK_STREQ("Apple", [webView stringByEvaluatingJavaScript:@"editor.querySelector('a').textContent"]);
760 EXPECT_WK_STREQ("https://www.apple.com/", [webView stringByEvaluatingJavaScript:@"editor.querySelector('a').href"]);
763 TEST(DataInteractionTests, ExternalSourceFileURL)
765 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
766 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
767 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
769 NSURL *URL = [NSURL URLWithString:@"file:///some/file/that/is/not/real"];
770 UIItemProvider *simulatedItemProvider = [UIItemProvider itemProviderWithURL:URL title:@""];
772 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
773 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider ]];
774 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
776 EXPECT_FALSE([[webView stringByEvaluatingJavaScript:@"!!editor.querySelector('a')"] boolValue]);
777 EXPECT_WK_STREQ("Hello world\nfile:///some/file/that/is/not/real", [webView stringByEvaluatingJavaScript:@"document.body.innerText"]);
780 TEST(DataInteractionTests, ExternalSourceOverrideDropFileUpload)
782 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
783 [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
785 auto simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]);
786 NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5);
787 [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData];
789 auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
790 NSData *firstHTMLData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding];
791 [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:firstHTMLData];
793 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
794 [dataInteractionSimulator setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session)
796 EXPECT_EQ(2UL, session.items.count);
797 UIDragItem *firstItem = session.items[0];
798 UIDragItem *secondItem = session.items[1];
799 EXPECT_TRUE([firstItem.itemProvider.registeredTypeIdentifiers isEqual:@[ (NSString *)kUTTypeJPEG ]]);
800 EXPECT_TRUE([secondItem.itemProvider.registeredTypeIdentifiers isEqual:@[ (NSString *)kUTTypeHTML ]]);
801 return @[ secondItem ];
803 [dataInteractionSimulator setExternalItemProviders:@[ simulatedImageItemProvider.get(), simulatedHTMLItemProvider.get() ]];
804 [dataInteractionSimulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)];
806 NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"];
807 EXPECT_WK_STREQ("text/html", outputValue.UTF8String);
810 TEST(DataInteractionTests, ExternalSourceOverrideDropInsertURL)
812 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
813 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
814 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
816 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
817 [dataInteractionSimulator setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session)
819 NSMutableArray<UIDragItem *> *allowedItems = [NSMutableArray array];
820 for (UIDragItem *item in session.items) {
821 if ([item.itemProvider.registeredTypeIdentifiers containsObject:(NSString *)kUTTypeURL])
822 [allowedItems addObject:item];
824 EXPECT_EQ(1UL, allowedItems.count);
828 auto firstItemProvider = adoptNS([[UIItemProvider alloc] init]);
829 [firstItemProvider registerObject:@"This is a string." visibility:UIItemProviderRepresentationOptionsVisibilityAll];
830 auto secondItemProvider = adoptNS([[UIItemProvider alloc] init]);
831 [secondItemProvider registerObject:[NSURL URLWithString:@"https://webkit.org/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll];
832 [dataInteractionSimulator setExternalItemProviders:@[ firstItemProvider.get(), secondItemProvider.get() ]];
833 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
835 EXPECT_WK_STREQ("https://webkit.org/", [webView stringByEvaluatingJavaScript:@"editor.textContent"]);
838 TEST(DataInteractionTests, OverrideDataInteractionOperation)
840 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
841 [webView synchronouslyLoadTestPageNamed:@"simple"];
843 RetainPtr<UIItemProvider> simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]);
844 [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:[@"<body></body>" dataUsingEncoding:NSUTF8StringEncoding]];
846 __block bool finishedLoadingData = false;
847 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
848 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]];
849 [dataInteractionSimulator setOverrideDataInteractionOperationBlock:^NSUInteger(NSUInteger operation, id session)
851 EXPECT_EQ(0U, operation);
854 [dataInteractionSimulator setDataInteractionOperationCompletionBlock:^(BOOL handled, NSArray *itemProviders) {
855 EXPECT_FALSE(handled);
856 [itemProviders.firstObject loadDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML completionHandler:^(NSData *data, NSError *error) {
857 NSString *text = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
858 EXPECT_WK_STREQ("<body></body>", text.UTF8String);
859 EXPECT_FALSE(!!error);
860 finishedLoadingData = true;
863 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
864 TestWebKitAPI::Util::run(&finishedLoadingData);
867 TEST(DataInteractionTests, InjectedBundleOverridePerformTwoStepDrop)
869 WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"];
870 [configuration.processPool _setObject:@YES forBundleParameter:@"BundleOverridePerformTwoStepDrop"];
872 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]);
873 [webView loadTestPageNamed:@"autofocus-contenteditable"];
874 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
876 auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]);
877 [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock)
879 completionBlock([@"Hello world" dataUsingEncoding:NSUTF8StringEncoding], nil);
880 return [NSProgress discreteProgressWithTotalUnitCount:100];
883 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
884 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]];
885 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
887 EXPECT_EQ(0UL, [webView stringByEvaluatingJavaScript:@"editor.textContent"].length);
890 TEST(DataInteractionTests, InjectedBundleAllowPerformTwoStepDrop)
892 WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"];
893 [configuration.processPool _setObject:@NO forBundleParameter:@"BundleOverridePerformTwoStepDrop"];
895 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]);
896 [webView loadTestPageNamed:@"autofocus-contenteditable"];
897 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
899 auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]);
900 [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock)
902 completionBlock([@"Hello world" dataUsingEncoding:NSUTF8StringEncoding], nil);
903 return [NSProgress discreteProgressWithTotalUnitCount:100];
906 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
907 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]];
908 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
910 EXPECT_WK_STREQ("Hello world", [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String);
913 TEST(DataInteractionTests, InjectedBundleImageElementData)
915 WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"];
916 [configuration _setAttachmentElementEnabled:YES];
917 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]);
918 [webView synchronouslyLoadTestPageNamed:@"image-and-contenteditable"];
920 __block RetainPtr<NSString> injectedString;
921 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
922 [dataInteractionSimulator setConvertItemProvidersBlock:^NSArray *(UIItemProvider *itemProvider, NSArray *, NSDictionary *data)
924 injectedString = adoptNS([[NSString alloc] initWithData:data[InjectedBundlePasteboardDataType] encoding:NSUTF8StringEncoding]);
925 return @[ itemProvider ];
928 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 250)];
930 EXPECT_WK_STREQ("hello", [injectedString UTF8String]);
933 TEST(DataInteractionTests, InjectedBundleAttachmentElementData)
935 WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"];
936 [configuration _setAttachmentElementEnabled:YES];
937 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]);
938 [webView synchronouslyLoadTestPageNamed:@"attachment-element"];
940 __block RetainPtr<NSString> injectedString;
941 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
942 [dataInteractionSimulator setConvertItemProvidersBlock:^NSArray *(UIItemProvider *itemProvider, NSArray *, NSDictionary *data)
944 injectedString = adoptNS([[NSString alloc] initWithData:data[InjectedBundlePasteboardDataType] encoding:NSUTF8StringEncoding]);
945 return @[ itemProvider ];
948 [dataInteractionSimulator runFrom:CGPointMake(50, 50) to:CGPointMake(50, 400)];
950 EXPECT_WK_STREQ("hello", [injectedString UTF8String]);
951 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"getSelection().isCollapsed"].boolValue);
954 TEST(DataInteractionTests, LargeImageToTargetDiv)
956 auto testWebViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
957 [[testWebViewConfiguration preferences] _setLargeImageAsyncDecodingEnabled:NO];
959 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:testWebViewConfiguration.get()]);
960 [webView synchronouslyLoadTestPageNamed:@"div-and-large-image"];
962 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
963 [dataInteractionSimulator runFrom:CGPointMake(200, 400) to:CGPointMake(200, 150)];
964 EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target.textContent"].UTF8String);
965 checkTypeIdentifierPrecedesOtherTypeIdentifier(dataInteractionSimulator.get(), (NSString *)kUTTypePNG, (NSString *)kUTTypeFileURL);
966 checkSuggestedNameAndEstimatedSize(dataInteractionSimulator.get(), @"large-red-square.png", { 2000, 2000 });
969 TEST(DataInteractionTests, LinkWithEmptyHREF)
971 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
972 [webView synchronouslyLoadTestPageNamed:@"link-and-input"];
973 [webView stringByEvaluatingJavaScript:@"document.querySelector('a').href = ''"];
975 RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
976 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
978 EXPECT_EQ(DataInteractionCancelled, [dataInteractionSimulator phase]);
979 EXPECT_WK_STREQ("", [webView editorValue].UTF8String);
982 TEST(DataInteractionTests, CancelledLiftDoesNotCauseSubsequentDragsToFail)
984 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
985 [webView synchronouslyLoadTestPageNamed:@"link-and-target-div"];
987 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
988 [dataInteractionSimulator setConvertItemProvidersBlock:^NSArray *(UIItemProvider *, NSArray *, NSDictionary *)
992 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
993 EXPECT_EQ(DataInteractionCancelled, [dataInteractionSimulator phase]);
994 EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"target.textContent"]);
995 NSString *outputText = [webView stringByEvaluatingJavaScript:@"output.textContent"];
996 checkStringArraysAreEqual(@[@"dragstart", @"dragend"], [outputText componentsSeparatedByString:@" "]);
998 [webView stringByEvaluatingJavaScript:@"output.innerHTML = ''"];
999 [dataInteractionSimulator setConvertItemProvidersBlock:^NSArray *(UIItemProvider *itemProvider, NSArray *, NSDictionary *)
1001 return @[ itemProvider ];
1003 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
1004 EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target.textContent"]);
1005 [webView stringByEvaluatingJavaScript:@"output.textContent"];
1006 checkStringArraysAreEqual(@[@"dragstart", @"dragend"], [outputText componentsSeparatedByString:@" "]);
1009 TEST(DataInteractionTests, CustomActionSheetPopover)
1011 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
1012 [webView synchronouslyLoadTestPageNamed:@"link-and-target-div"];
1014 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
1015 [dataInteractionSimulator setShouldEnsureUIApplication:YES];
1017 __block BOOL didInvokeCustomActionSheet = NO;
1018 [dataInteractionSimulator setShowCustomActionSheetBlock:^BOOL(_WKActivatedElementInfo *element)
1020 EXPECT_EQ(_WKActivatedElementTypeLink, element.type);
1021 EXPECT_WK_STREQ("Hello world", element.title.UTF8String);
1022 didInvokeCustomActionSheet = YES;
1025 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
1026 EXPECT_TRUE(didInvokeCustomActionSheet);
1027 EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target.textContent"].UTF8String);
1030 TEST(DataInteractionTests, UnresponsivePageDoesNotHangUI)
1032 _WKProcessPoolConfiguration *processPoolConfiguration = [[[_WKProcessPoolConfiguration alloc] init] autorelease];
1033 processPoolConfiguration.ignoreSynchronousMessagingTimeoutsForTesting = YES;
1035 RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:[[[WKWebViewConfiguration alloc] init] autorelease] processPoolConfiguration:processPoolConfiguration]);
1036 [webView synchronouslyLoadTestPageNamed:@"simple"];
1037 [webView evaluateJavaScript:@"while(1);" completionHandler:nil];
1039 // The test passes if we can prepare for data interaction without timing out.
1040 [webView _simulatePrepareForDataInteractionSession:nil completion:^() { }];
1043 TEST(DataInteractionTests, WebItemProviderPasteboardLoading)
1045 static NSString *fastString = @"This data loads quickly";
1046 static NSString *slowString = @"This data loads slowly";
1048 WebItemProviderPasteboard *pasteboard = [WebItemProviderPasteboard sharedInstance];
1049 auto fastItem = adoptNS([[UIItemProvider alloc] init]);
1050 [fastItem registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock)
1052 completionBlock([fastString dataUsingEncoding:NSUTF8StringEncoding], nil);
1056 auto slowItem = adoptNS([[UIItemProvider alloc] init]);
1057 [slowItem registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock)
1060 completionBlock([slowString dataUsingEncoding:NSUTF8StringEncoding], nil);
1064 __block bool hasRunFirstCompletionBlock = false;
1065 pasteboard.itemProviders = @[ fastItem.get(), slowItem.get() ];
1066 [pasteboard doAfterLoadingProvidedContentIntoFileURLs:^(NSArray<NSURL *> *urls) {
1067 EXPECT_EQ(2UL, urls.count);
1068 auto firstString = adoptNS([[NSString alloc] initWithContentsOfURL:urls[0] encoding:NSUTF8StringEncoding error:nil]);
1069 auto secondString = adoptNS([[NSString alloc] initWithContentsOfURL:urls[1] encoding:NSUTF8StringEncoding error:nil]);
1070 EXPECT_WK_STREQ(fastString, [firstString UTF8String]);
1071 EXPECT_WK_STREQ(slowString, [secondString UTF8String]);
1072 hasRunFirstCompletionBlock = true;
1073 } synchronousTimeout:600];
1074 EXPECT_TRUE(hasRunFirstCompletionBlock);
1076 __block bool hasRunSecondCompletionBlock = false;
1077 [pasteboard doAfterLoadingProvidedContentIntoFileURLs:^(NSArray<NSURL *> *urls) {
1078 EXPECT_EQ(2UL, urls.count);
1079 auto firstString = adoptNS([[NSString alloc] initWithContentsOfURL:urls[0] encoding:NSUTF8StringEncoding error:nil]);
1080 auto secondString = adoptNS([[NSString alloc] initWithContentsOfURL:urls[1] encoding:NSUTF8StringEncoding error:nil]);
1081 EXPECT_WK_STREQ(fastString, [firstString UTF8String]);
1082 EXPECT_WK_STREQ(slowString, [secondString UTF8String]);
1083 hasRunSecondCompletionBlock = true;
1084 } synchronousTimeout:0];
1085 EXPECT_FALSE(hasRunSecondCompletionBlock);
1086 TestWebKitAPI::Util::run(&hasRunSecondCompletionBlock);
1089 TEST(DataInteractionTests, DoNotCrashWhenSelectionMovesOffscreenAfterDragStart)
1091 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
1092 [webView synchronouslyLoadTestPageNamed:@"dragstart-change-selection-offscreen"];
1094 auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
1095 [simulator runFrom:CGPointMake(100, 100) to:CGPointMake(100, 100)];
1097 EXPECT_WK_STREQ("FAR OFFSCREEN", [webView stringByEvaluatingJavaScript:@"getSelection().getRangeAt(0).toString()"]);
1100 } // namespace TestWebKitAPI
1102 #endif // ENABLE(DATA_INTERACTION)