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/NSItemProvider+UIKitAdditions.h>
36 #import <WebKit/WKPreferencesPrivate.h>
37 #import <WebKit/WKProcessPoolPrivate.h>
38 #import <WebKit/WKWebViewConfigurationPrivate.h>
39 #import <WebKit/WebItemProviderPasteboard.h>
40 #import <WebKit/_WKProcessPoolConfiguration.h>
42 typedef void (^FileLoadCompletionBlock)(NSURL *, BOOL, NSError *);
43 typedef void (^DataLoadCompletionBlock)(NSData *, NSError *);
44 typedef void (^UIItemProviderDataLoadCompletionBlock)(NSData *, NSError *);
46 #if !USE(APPLE_INTERNAL_SDK)
48 @interface UIItemProviderRepresentationOptions : NSObject
53 @interface UIItemProvider()
54 + (UIItemProvider *)itemProviderWithURL:(NSURL *)url title:(NSString *)title;
55 - (void) registerDataRepresentationForTypeIdentifier:(NSString *)typeIdentifier options:(UIItemProviderRepresentationOptions*)options loadHandler:(NSProgress * (^)(void (^UIItemProviderDataLoadCompletionBlock)(NSData *item, NSError *error))) loadHandler;
58 static NSString *InjectedBundlePasteboardDataType = @"org.webkit.data";
60 static UIImage *testIconImage()
62 return [UIImage imageNamed:@"TestWebKitAPI.resources/icon.png"];
65 static NSData *testZIPArchive()
67 NSURL *zipFileURL = [[NSBundle mainBundle] URLForResource:@"compressed-files" withExtension:@"zip" subdirectory:@"TestWebKitAPI.resources"];
68 return [NSData dataWithContentsOfURL:zipFileURL];
71 @implementation UIItemProvider (DataInteractionTests)
73 - (void)registerDataRepresentationForTypeIdentifier:(NSString *)typeIdentifier withData:(NSData *)data
75 RetainPtr<NSData> retainedData = data;
76 [self registerDataRepresentationForTypeIdentifier:typeIdentifier visibility:UIItemProviderRepresentationOptionsVisibilityAll loadHandler: [retainedData] (DataLoadCompletionBlock block) -> NSProgress * {
77 block(retainedData.get(), nil);
78 return [NSProgress discreteProgressWithTotalUnitCount:100];
84 @implementation TestWKWebView (DataInteractionTests)
86 - (BOOL)editorContainsImageElement
88 return [self stringByEvaluatingJavaScript:@"!!editor.querySelector('img')"].boolValue;
91 - (NSString *)editorValue
93 return [self stringByEvaluatingJavaScript:@"editor.value"];
98 static NSValue *makeCGRectValue(CGFloat x, CGFloat y, CGFloat width, CGFloat height)
100 return [NSValue valueWithCGRect:CGRectMake(x, y, width, height)];
103 static void checkSelectionRectsWithLogging(NSArray *expected, NSArray *observed)
105 if (![expected isEqualToArray:observed])
106 NSLog(@"Expected selection rects: %@ but observed: %@", expected, observed);
107 EXPECT_TRUE([expected isEqualToArray:observed]);
110 static void checkTypeIdentifierPrecedesOtherTypeIdentifier(DataInteractionSimulator *simulator, NSString *firstType, NSString *secondType)
112 NSArray *registeredTypes = [simulator.sourceItemProviders.firstObject registeredTypeIdentifiers];
113 EXPECT_TRUE([registeredTypes containsObject:firstType]);
114 EXPECT_TRUE([registeredTypes containsObject:secondType]);
115 EXPECT_TRUE([registeredTypes indexOfObject:firstType] < [registeredTypes indexOfObject:secondType]);
118 static void checkTypeIdentifierAndIsNotOtherTypeIdentifier(DataInteractionSimulator *simulator, NSString *firstType, NSString *secondType)
120 NSArray *registeredTypes = [simulator.sourceItemProviders.firstObject registeredTypeIdentifiers];
121 EXPECT_TRUE([registeredTypes containsObject:firstType]);
122 EXPECT_FALSE([registeredTypes containsObject:secondType]);
125 static void checkTypeIdentifierIsRegisteredAtIndex(DataInteractionSimulator *simulator, NSString *type, NSUInteger index)
127 NSArray *registeredTypes = [simulator.sourceItemProviders.firstObject registeredTypeIdentifiers];
128 EXPECT_GT(registeredTypes.count, index);
129 EXPECT_WK_STREQ(type.UTF8String, [registeredTypes[index] UTF8String]);
132 static void checkEstimatedSize(DataInteractionSimulator *simulator, CGSize estimatedSize)
134 UIItemProvider *sourceItemProvider = [simulator sourceItemProviders].firstObject;
135 EXPECT_EQ(estimatedSize.width, sourceItemProvider.preferredPresentationSize.width);
136 EXPECT_EQ(estimatedSize.height, sourceItemProvider.preferredPresentationSize.height);
139 static void checkSuggestedNameAndEstimatedSize(DataInteractionSimulator *simulator, NSString *suggestedName, CGSize estimatedSize)
141 UIItemProvider *sourceItemProvider = [simulator sourceItemProviders].firstObject;
142 EXPECT_WK_STREQ(suggestedName.UTF8String, sourceItemProvider.suggestedName.UTF8String);
143 EXPECT_EQ(estimatedSize.width, sourceItemProvider.preferredPresentationSize.width);
144 EXPECT_EQ(estimatedSize.height, sourceItemProvider.preferredPresentationSize.height);
147 static void checkStringArraysAreEqual(NSArray<NSString *> *expected, NSArray<NSString *> *observed)
149 EXPECT_EQ(expected.count, observed.count);
150 for (NSUInteger index = 0; index < expected.count; ++index) {
151 NSString *expectedString = [expected objectAtIndex:index];
152 NSString *observedString = [observed objectAtIndex:index];
153 EXPECT_WK_STREQ(expectedString, observedString);
154 if (![expectedString isEqualToString:observedString])
155 NSLog(@"Expected observed string: %@ to match expected string: %@ at index: %tu", observedString, expectedString, index);
159 static void checkDragCaretRectIsContainedInRect(CGRect caretRect, CGRect containerRect)
161 BOOL contained = CGRectContainsRect(containerRect, caretRect);
162 EXPECT_TRUE(contained);
164 NSLog(@"Expected caret rect: %@ to fit within container rect: %@", NSStringFromCGRect(caretRect), NSStringFromCGRect(containerRect));
167 namespace TestWebKitAPI {
169 TEST(DataInteractionTests, ImageToContentEditable)
171 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
172 [webView synchronouslyLoadTestPageNamed:@"image-and-contenteditable"];
174 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
175 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
177 EXPECT_TRUE([webView editorContainsImageElement]);
179 NSArray *observedEventNames = [dataInteractionSimulator observedEventNames];
180 EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]);
181 EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]);
182 EXPECT_TRUE([observedEventNames containsObject:DataInteractionPerformOperationEventName]);
183 checkSelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 215, 174) ], [dataInteractionSimulator finalSelectionRects]);
184 checkTypeIdentifierAndIsNotOtherTypeIdentifier(dataInteractionSimulator.get(), (NSString *)kUTTypePNG, (NSString *)kUTTypeFileURL);
185 checkEstimatedSize(dataInteractionSimulator.get(), { 215, 174 });
188 TEST(DataInteractionTests, CanStartDragOnEnormousImage)
190 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
191 [webView synchronouslyLoadHTMLString:@"<img src='enormous.svg'></img>"];
193 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
194 [dataInteractionSimulator runFrom:CGPointMake(100, 100) to:CGPointMake(100, 100)];
196 NSArray *registeredTypes = [[dataInteractionSimulator sourceItemProviders].firstObject registeredTypeIdentifiers];
197 EXPECT_WK_STREQ((NSString *)kUTTypeScalableVectorGraphics, [registeredTypes firstObject]);
200 TEST(DataInteractionTests, ImageToTextarea)
202 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
203 [webView synchronouslyLoadTestPageNamed:@"image-and-textarea"];
205 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
206 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
208 EXPECT_WK_STREQ("", [webView editorValue]);
210 NSArray *observedEventNames = [dataInteractionSimulator observedEventNames];
211 EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]);
212 EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]);
213 EXPECT_TRUE([observedEventNames containsObject:DataInteractionPerformOperationEventName]);
214 checkTypeIdentifierAndIsNotOtherTypeIdentifier(dataInteractionSimulator.get(), (NSString *)kUTTypePNG, (NSString *)kUTTypeFileURL);
215 checkEstimatedSize(dataInteractionSimulator.get(), { 215, 174 });
218 TEST(DataInteractionTests, ImageInLinkToInput)
220 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
221 [webView synchronouslyLoadTestPageNamed:@"image-in-link-and-input"];
223 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
224 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
226 EXPECT_WK_STREQ("https://www.apple.com/", [webView editorValue].UTF8String);
227 checkSelectionRectsWithLogging(@[ makeCGRectValue(101, 241, 2057, 232) ], [dataInteractionSimulator finalSelectionRects]);
228 checkSuggestedNameAndEstimatedSize(dataInteractionSimulator.get(), @"icon.png", { 215, 174 });
229 checkTypeIdentifierIsRegisteredAtIndex(dataInteractionSimulator.get(), (NSString *)kUTTypePNG, 0);
232 TEST(DataInteractionTests, ImageInLinkWithoutHREFToInput)
234 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
235 [webView synchronouslyLoadTestPageNamed:@"image-in-link-and-input"];
236 [webView stringByEvaluatingJavaScript:@"link.href = ''"];
238 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
239 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
241 EXPECT_WK_STREQ("", [webView editorValue]);
242 checkEstimatedSize(dataInteractionSimulator.get(), { 215, 174 });
243 checkTypeIdentifierIsRegisteredAtIndex(dataInteractionSimulator.get(), (NSString *)kUTTypePNG, 0);
246 TEST(DataInteractionTests, ImageDoesNotUseElementSizeAsEstimatedSize)
248 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
249 [webView synchronouslyLoadTestPageNamed:@"gif-and-file-input"];
251 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
252 [dataInteractionSimulator runFrom: { 100, 100 } to: { 100, 300 }];
254 checkTypeIdentifierIsRegisteredAtIndex(dataInteractionSimulator.get(), (NSString *)kUTTypeGIF, 0);
255 checkSuggestedNameAndEstimatedSize(dataInteractionSimulator.get(), @"apple.gif", { 52, 64 });
256 EXPECT_WK_STREQ("apple.gif (image/gif)", [webView stringByEvaluatingJavaScript:@"output.textContent"]);
259 TEST(DataInteractionTests, ContentEditableToContentEditable)
261 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
262 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
264 [webView loadTestPageNamed:@"autofocus-contenteditable"];
265 [dataInteractionSimulator waitForInputSession];
266 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
268 EXPECT_EQ([webView stringByEvaluatingJavaScript:@"source.textContent"].length, 0UL);
269 EXPECT_WK_STREQ("Hello world", [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String);
271 NSArray *observedEventNames = [dataInteractionSimulator observedEventNames];
272 EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]);
273 EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]);
274 EXPECT_TRUE([observedEventNames containsObject:DataInteractionPerformOperationEventName]);
275 checkSelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 961, 227) ], [dataInteractionSimulator finalSelectionRects]);
276 checkTypeIdentifierPrecedesOtherTypeIdentifier(dataInteractionSimulator.get(), (NSString *)kUTTypeRTFD, (NSString *)kUTTypeUTF8PlainText);
279 TEST(DataInteractionTests, ContentEditableToTextarea)
281 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
282 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
284 [webView loadTestPageNamed:@"contenteditable-and-textarea"];
285 [dataInteractionSimulator waitForInputSession];
286 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
288 EXPECT_EQ([webView stringByEvaluatingJavaScript:@"source.textContent"].length, 0UL);
289 EXPECT_WK_STREQ("Hello world", [webView editorValue].UTF8String);
291 NSArray *observedEventNames = [dataInteractionSimulator observedEventNames];
292 EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]);
293 EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]);
294 EXPECT_TRUE([observedEventNames containsObject:DataInteractionPerformOperationEventName]);
295 checkSelectionRectsWithLogging(@[ makeCGRectValue(6, 203, 990, 232) ], [dataInteractionSimulator finalSelectionRects]);
296 checkTypeIdentifierPrecedesOtherTypeIdentifier(dataInteractionSimulator.get(), (NSString *)kUTTypeRTFD, (NSString *)kUTTypeUTF8PlainText);
299 TEST(DataInteractionTests, ContentEditableMoveParagraphs)
301 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
302 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
304 [webView loadTestPageNamed:@"two-paragraph-contenteditable"];
305 [dataInteractionSimulator waitForInputSession];
306 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(250, 450)];
308 NSString *finalTextContent = [webView stringByEvaluatingJavaScript:@"editor.textContent"];
309 NSUInteger firstParagraphOffset = [finalTextContent rangeOfString:@"This is the first paragraph"].location;
310 NSUInteger secondParagraphOffset = [finalTextContent rangeOfString:@"This is the second paragraph"].location;
312 EXPECT_FALSE(firstParagraphOffset == NSNotFound);
313 EXPECT_FALSE(secondParagraphOffset == NSNotFound);
314 EXPECT_GT(firstParagraphOffset, secondParagraphOffset);
315 checkSelectionRectsWithLogging(@[ makeCGRectValue(190, 100, 130, 20), makeCGRectValue(0, 120, 320, 100), makeCGRectValue(0, 220, 252, 20) ], [dataInteractionSimulator finalSelectionRects]);
318 TEST(DataInteractionTests, DragImageFromContentEditable)
320 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
321 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
323 [webView synchronouslyLoadTestPageNamed:@"contenteditable-and-target"];
324 [dataInteractionSimulator runFrom:CGPointMake(100, 100) to:CGPointMake(100, 300)];
326 EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target.textContent"]);
329 TEST(DataInteractionTests, TextAreaToInput)
331 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
332 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
334 [webView loadTestPageNamed:@"textarea-to-input"];
335 [dataInteractionSimulator waitForInputSession];
336 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
338 EXPECT_EQ([webView stringByEvaluatingJavaScript:@"source.value"].length, 0UL);
339 EXPECT_WK_STREQ("Hello world", [webView editorValue].UTF8String);
340 checkSelectionRectsWithLogging(@[ makeCGRectValue(101, 241, 990, 232) ], [dataInteractionSimulator finalSelectionRects]);
343 TEST(DataInteractionTests, SinglePlainTextWordTypeIdentifiers)
345 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
346 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
348 [webView loadTestPageNamed:@"textarea-to-input"];
349 [dataInteractionSimulator waitForInputSession];
350 [webView stringByEvaluatingJavaScript:@"source.value = 'pneumonoultramicroscopicsilicovolcanoconiosis'"];
351 [webView stringByEvaluatingJavaScript:@"source.selectionStart = 0"];
352 [webView stringByEvaluatingJavaScript:@"source.selectionEnd = source.value.length"];
353 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
355 NSArray *registeredTypes = [[dataInteractionSimulator sourceItemProviders].firstObject registeredTypeIdentifiers];
356 EXPECT_EQ(1UL, registeredTypes.count);
357 EXPECT_WK_STREQ([(NSString *)kUTTypeUTF8PlainText UTF8String], [registeredTypes.firstObject UTF8String]);
358 EXPECT_EQ([webView stringByEvaluatingJavaScript:@"source.value"].length, 0UL);
359 EXPECT_WK_STREQ("pneumonoultramicroscopicsilicovolcanoconiosis", [webView editorValue].UTF8String);
362 TEST(DataInteractionTests, SinglePlainTextURLTypeIdentifiers)
364 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
365 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
367 [webView loadTestPageNamed:@"textarea-to-input"];
368 [dataInteractionSimulator waitForInputSession];
369 [webView stringByEvaluatingJavaScript:@"source.value = 'https://webkit.org/'"];
370 [webView stringByEvaluatingJavaScript:@"source.selectionStart = 0"];
371 [webView stringByEvaluatingJavaScript:@"source.selectionEnd = source.value.length"];
372 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
374 NSArray *registeredTypes = [[dataInteractionSimulator sourceItemProviders].firstObject registeredTypeIdentifiers];
375 EXPECT_EQ(2UL, registeredTypes.count);
376 EXPECT_WK_STREQ([(NSString *)kUTTypeURL UTF8String], [registeredTypes.firstObject UTF8String]);
377 EXPECT_WK_STREQ([(NSString *)kUTTypeUTF8PlainText UTF8String], [registeredTypes.lastObject UTF8String]);
378 EXPECT_EQ(0UL, [webView stringByEvaluatingJavaScript:@"source.value"].length);
379 EXPECT_WK_STREQ("https://webkit.org/", [webView editorValue].UTF8String);
382 TEST(DataInteractionTests, LinkToInput)
384 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
385 [webView synchronouslyLoadTestPageNamed:@"link-and-input"];
387 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
388 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
390 EXPECT_WK_STREQ("https://www.apple.com/", [webView editorValue].UTF8String);
392 __block bool doneLoadingURL = false;
393 UIItemProvider *sourceItemProvider = [dataInteractionSimulator sourceItemProviders].firstObject;
394 [sourceItemProvider loadObjectOfClass:[NSURL class] completionHandler:^(id object, NSError *error) {
396 EXPECT_WK_STREQ("Hello world", url._title.UTF8String ?: "");
397 doneLoadingURL = true;
399 TestWebKitAPI::Util::run(&doneLoadingURL);
401 NSArray *observedEventNames = [dataInteractionSimulator observedEventNames];
402 EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]);
403 EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]);
404 EXPECT_TRUE([observedEventNames containsObject:DataInteractionPerformOperationEventName]);
405 checkSelectionRectsWithLogging(@[ makeCGRectValue(101, 273, 2057, 232) ], [dataInteractionSimulator finalSelectionRects]);
406 checkTypeIdentifierIsRegisteredAtIndex(dataInteractionSimulator.get(), (NSString *)kUTTypeURL, 0);
409 TEST(DataInteractionTests, BackgroundImageLinkToInput)
411 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
412 [webView synchronouslyLoadTestPageNamed:@"background-image-link-and-input"];
414 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
415 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
417 EXPECT_WK_STREQ("https://www.apple.com/", [webView editorValue].UTF8String);
419 NSArray *observedEventNames = [dataInteractionSimulator observedEventNames];
420 EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]);
421 EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]);
422 EXPECT_TRUE([observedEventNames containsObject:DataInteractionPerformOperationEventName]);
423 checkSelectionRectsWithLogging(@[ makeCGRectValue(101, 241, 2057, 232) ], [dataInteractionSimulator finalSelectionRects]);
424 checkTypeIdentifierIsRegisteredAtIndex(dataInteractionSimulator.get(), (NSString *)kUTTypeURL, 0);
427 TEST(DataInteractionTests, CanPreventStart)
429 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
430 [webView synchronouslyLoadTestPageNamed:@"prevent-start"];
432 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
433 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
435 EXPECT_EQ(DataInteractionCancelled, [dataInteractionSimulator phase]);
436 EXPECT_FALSE([webView editorContainsImageElement]);
438 NSArray *observedEventNames = [dataInteractionSimulator observedEventNames];
439 EXPECT_FALSE([observedEventNames containsObject:DataInteractionEnterEventName]);
440 EXPECT_FALSE([observedEventNames containsObject:DataInteractionOverEventName]);
441 checkSelectionRectsWithLogging(@[ ], [dataInteractionSimulator finalSelectionRects]);
444 TEST(DataInteractionTests, CanPreventOperation)
446 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
447 [webView synchronouslyLoadTestPageNamed:@"prevent-operation"];
449 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
450 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
452 EXPECT_FALSE([webView editorContainsImageElement]);
454 NSArray *observedEventNames = [dataInteractionSimulator observedEventNames];
455 EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]);
456 EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]);
457 checkSelectionRectsWithLogging(@[ ], [dataInteractionSimulator finalSelectionRects]);
460 TEST(DataInteractionTests, EnterAndLeaveEvents)
462 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
463 [webView synchronouslyLoadTestPageNamed:@"link-and-input"];
465 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
466 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 450)];
468 EXPECT_WK_STREQ("", [webView editorValue].UTF8String);
470 NSArray *observedEventNames = [dataInteractionSimulator observedEventNames];
471 EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]);
472 EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]);
473 EXPECT_TRUE([observedEventNames containsObject:DataInteractionLeaveEventName]);
474 EXPECT_FALSE([observedEventNames containsObject:DataInteractionPerformOperationEventName]);
475 checkSelectionRectsWithLogging(@[ ], [dataInteractionSimulator finalSelectionRects]);
478 TEST(DataInteractionTests, ExternalSourcePlainTextToIFrame)
480 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
481 [webView synchronouslyLoadTestPageNamed:@"contenteditable-in-iframe"];
483 auto itemProvider = adoptNS([[UIItemProvider alloc] init]);
484 [itemProvider registerObject:@"Hello world" visibility:UIItemProviderRepresentationOptionsVisibilityAll];
486 auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
487 [simulator setExternalItemProviders:@[ itemProvider.get() ]];
488 [simulator runFrom:CGPointMake(0, 0) to:CGPointMake(160, 250)];
490 auto containerLeft = [webView stringByEvaluatingJavaScript:@"container.getBoundingClientRect().left"].floatValue;
491 auto containerTop = [webView stringByEvaluatingJavaScript:@"container.getBoundingClientRect().top"].floatValue;
492 auto containerWidth = [webView stringByEvaluatingJavaScript:@"container.getBoundingClientRect().width"].floatValue;
493 auto containerHeight = [webView stringByEvaluatingJavaScript:@"container.getBoundingClientRect().height"].floatValue;
494 checkDragCaretRectIsContainedInRect([simulator lastKnownDragCaretRect], CGRectMake(containerLeft, containerTop, containerWidth, containerHeight));
497 TEST(DataInteractionTests, ExternalSourceJSONToFileInput)
499 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
500 [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
502 auto simulatedJSONItemProvider = adoptNS([[UIItemProvider alloc] init]);
503 NSData *jsonData = [@"{ \"foo\": \"bar\", \"bar\": \"baz\" }" dataUsingEncoding:NSUTF8StringEncoding];
504 [simulatedJSONItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJSON withData:jsonData];
506 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
507 [dataInteractionSimulator setExternalItemProviders:@[ simulatedJSONItemProvider.get() ]];
508 [dataInteractionSimulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)];
510 EXPECT_WK_STREQ("application/json", [webView stringByEvaluatingJavaScript:@"output.value"]);
513 TEST(DataInteractionTests, ExternalSourceImageToFileInput)
515 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
516 [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
518 auto simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]);
519 NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5);
520 [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData];
522 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
523 [dataInteractionSimulator setExternalItemProviders:@[ simulatedImageItemProvider.get() ]];
524 [dataInteractionSimulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)];
526 NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"];
527 EXPECT_WK_STREQ("image/jpeg", outputValue.UTF8String);
530 TEST(DataInteractionTests, ExternalSourceHTMLToUploadArea)
532 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
533 [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
535 auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
536 NSData *htmlData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding];
537 [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData];
539 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
540 [dataInteractionSimulator setShouldAllowMoveOperation:NO];
541 [dataInteractionSimulator setExternalItemProviders:@[ simulatedHTMLItemProvider.get() ]];
542 [dataInteractionSimulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)];
544 NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"];
545 EXPECT_WK_STREQ("text/html", outputValue.UTF8String);
548 TEST(DataInteractionTests, ExternalSourceMoveOperationNotAllowed)
550 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
551 [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
552 [webView stringByEvaluatingJavaScript:@"upload.dropEffect = 'move'"];
554 auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
555 NSData *htmlData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding];
556 [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData];
558 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
559 [dataInteractionSimulator setShouldAllowMoveOperation:NO];
560 [dataInteractionSimulator setExternalItemProviders:@[ simulatedHTMLItemProvider.get() ]];
561 [dataInteractionSimulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)];
563 EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"output.value"]);
566 TEST(DataInteractionTests, ExternalSourceZIPArchiveAndURLToSingleFileInput)
568 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
569 [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
571 auto archiveProvider = adoptNS([[UIItemProvider alloc] init]);
572 [archiveProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeZipArchive withData:testZIPArchive()];
574 auto urlProvider = adoptNS([[UIItemProvider alloc] init]);
575 [urlProvider registerObject:[NSURL URLWithString:@"https://webkit.org"] visibility:UIItemProviderRepresentationOptionsVisibilityAll];
577 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
578 [dataInteractionSimulator setExternalItemProviders:@[ archiveProvider.get(), urlProvider.get() ]];
579 [dataInteractionSimulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)];
581 NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"];
582 EXPECT_WK_STREQ("application/zip", outputValue.UTF8String);
585 TEST(DataInteractionTests, ExternalSourceZIPArchiveToUploadArea)
587 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
588 [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
590 auto itemProvider = adoptNS([[UIItemProvider alloc] init]);
591 [itemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeZipArchive withData:testZIPArchive()];
593 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
594 [dataInteractionSimulator setExternalItemProviders:@[ itemProvider.get() ]];
595 [dataInteractionSimulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)];
597 NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"];
598 EXPECT_WK_STREQ("application/zip", outputValue.UTF8String);
601 TEST(DataInteractionTests, ExternalSourceImageAndHTMLToSingleFileInput)
603 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
604 [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
606 auto simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]);
607 NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5);
608 [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData];
610 auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
611 NSData *htmlData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding];
612 [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData];
614 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
615 [dataInteractionSimulator setExternalItemProviders:@[ simulatedHTMLItemProvider.get(), simulatedImageItemProvider.get() ]];
616 [dataInteractionSimulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)];
618 NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"];
619 EXPECT_WK_STREQ("", outputValue.UTF8String);
622 TEST(DataInteractionTests, ExternalSourceImageAndHTMLToMultipleFileInput)
624 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
625 [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
626 [webView stringByEvaluatingJavaScript:@"input.setAttribute('multiple', '')"];
628 auto simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]);
629 NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5);
630 [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData];
632 auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
633 NSData *htmlData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding];
634 [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData];
636 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
637 [dataInteractionSimulator setExternalItemProviders:@[ simulatedHTMLItemProvider.get(), simulatedImageItemProvider.get() ]];
638 [dataInteractionSimulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)];
640 NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"];
641 EXPECT_WK_STREQ("image/jpeg, text/html", outputValue.UTF8String);
644 TEST(DataInteractionTests, ExternalSourceImageAndHTMLToUploadArea)
646 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
647 [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
649 auto simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]);
650 NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5);
651 [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData];
653 auto firstSimulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
654 NSData *firstHTMLData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding];
655 [firstSimulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:firstHTMLData];
657 auto secondSimulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
658 NSData *secondHTMLData = [@"<html><body>hello world</body></html>" dataUsingEncoding:NSUTF8StringEncoding];
659 [secondSimulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:secondHTMLData];
661 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
662 [dataInteractionSimulator setShouldAllowMoveOperation:NO];
663 [dataInteractionSimulator setExternalItemProviders:@[ simulatedImageItemProvider.get(), firstSimulatedHTMLItemProvider.get(), secondSimulatedHTMLItemProvider.get() ]];
664 [dataInteractionSimulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)];
666 NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"];
667 EXPECT_WK_STREQ("image/jpeg, text/html, text/html", outputValue.UTF8String);
670 TEST(DataInteractionTests, ExternalSourceHTMLToContentEditable)
672 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
673 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
674 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
676 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
677 auto itemProvider = adoptNS([[UIItemProvider alloc] init]);
678 NSData *htmlData = [@"<h1>This is a test</h1>" dataUsingEncoding:NSUTF8StringEncoding];
679 [itemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData];
680 [dataInteractionSimulator setExternalItemProviders:@[ itemProvider.get() ]];
681 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
683 NSString *textContent = [webView stringByEvaluatingJavaScript:@"editor.textContent"];
684 EXPECT_WK_STREQ("This is a test", textContent.UTF8String);
685 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"!!editor.querySelector('h1')"].boolValue);
688 TEST(DataInteractionTests, ExternalSourceAttributedStringToContentEditable)
690 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
691 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
692 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
694 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
695 NSDictionary *textAttributes = @{ NSFontAttributeName: [UIFont boldSystemFontOfSize:20] };
696 NSAttributedString *richText = [[NSAttributedString alloc] initWithString:@"This is a test" attributes:textAttributes];
697 auto itemProvider = adoptNS([[UIItemProvider alloc] initWithObject:richText]);
698 [dataInteractionSimulator setExternalItemProviders:@[ itemProvider.get() ]];
699 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
701 EXPECT_WK_STREQ("This is a test", [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String);
704 TEST(DataInteractionTests, ExternalSourceMultipleURLsToContentEditable)
706 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
707 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
708 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
710 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
711 auto firstItem = adoptNS([[UIItemProvider alloc] init]);
712 [firstItem registerObject:[NSURL URLWithString:@"https://www.apple.com/iphone/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll];
713 auto secondItem = adoptNS([[UIItemProvider alloc] init]);
714 [secondItem registerObject:[NSURL URLWithString:@"https://www.apple.com/mac/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll];
715 auto thirdItem = adoptNS([[UIItemProvider alloc] init]);
716 [thirdItem registerObject:[NSURL URLWithString:@"https://webkit.org/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll];
717 [dataInteractionSimulator setExternalItemProviders:@[ firstItem.get(), secondItem.get(), thirdItem.get() ]];
718 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
720 NSArray *separatedLinks = [[webView stringByEvaluatingJavaScript:@"editor.textContent"] componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
721 EXPECT_EQ(3UL, separatedLinks.count);
722 EXPECT_WK_STREQ("https://www.apple.com/iphone/", separatedLinks[0]);
723 EXPECT_WK_STREQ("https://www.apple.com/mac/", separatedLinks[1]);
724 EXPECT_WK_STREQ("https://webkit.org/", separatedLinks[2]);
727 TEST(DataInteractionTests, RespectsExternalSourceFidelityRankings)
729 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
730 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
731 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
733 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
735 // Here, our source item provider vends two representations: plain text, and then an image. If we don't respect the
736 // fidelity order requested by the source, we'll end up assuming that the image is a higher fidelity representation
737 // than the plain text, and erroneously insert the image. If we respect source fidelities, we'll insert text rather
739 auto simulatedItemProviderWithTextFirst = adoptNS([[UIItemProvider alloc] init]);
740 [simulatedItemProviderWithTextFirst registerObject:@"Hello world" visibility:UIItemProviderRepresentationOptionsVisibilityAll];
741 [simulatedItemProviderWithTextFirst registerObject:testIconImage() visibility:UIItemProviderRepresentationOptionsVisibilityAll];
742 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProviderWithTextFirst.get() ]];
744 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
745 EXPECT_WK_STREQ("Hello world", [webView stringByEvaluatingJavaScript:@"editor.textContent"]);
746 EXPECT_FALSE([webView editorContainsImageElement]);
747 [webView stringByEvaluatingJavaScript:@"editor.innerHTML = ''"];
749 // Now we register the item providers in reverse, and expect the image to be inserted instead of text.
750 auto simulatedItemProviderWithImageFirst = adoptNS([[UIItemProvider alloc] init]);
751 [simulatedItemProviderWithImageFirst registerObject:testIconImage() visibility:UIItemProviderRepresentationOptionsVisibilityAll];
752 [simulatedItemProviderWithImageFirst registerObject:@"Hello world" visibility:UIItemProviderRepresentationOptionsVisibilityAll];
753 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProviderWithImageFirst.get() ]];
755 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
756 EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"editor.textContent"]);
757 EXPECT_TRUE([webView editorContainsImageElement]);
760 TEST(DataInteractionTests, ExternalSourceUTF8PlainTextOnly)
762 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
763 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
765 NSString *textPayload = @"Ceci n'est pas une string";
766 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
767 auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]);
768 [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock)
770 completionBlock([textPayload dataUsingEncoding:NSUTF8StringEncoding], nil);
771 return [NSProgress discreteProgressWithTotalUnitCount:100];
773 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]];
774 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
775 EXPECT_WK_STREQ(textPayload.UTF8String, [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String);
776 checkSelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 1936, 227) ], [dataInteractionSimulator finalSelectionRects]);
779 TEST(DataInteractionTests, ExternalSourceJPEGOnly)
781 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
782 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
784 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
785 auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]);
786 [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypeJPEG options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock)
788 completionBlock(UIImageJPEGRepresentation(testIconImage(), 0.5), nil);
789 return [NSProgress discreteProgressWithTotalUnitCount:100];
791 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]];
792 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
793 EXPECT_TRUE([webView editorContainsImageElement]);
794 checkSelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 215, 174) ], [dataInteractionSimulator finalSelectionRects]);
797 TEST(DataInteractionTests, ExternalSourceTitledNSURL)
799 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
800 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
801 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
803 NSURL *titledURL = [NSURL URLWithString:@"https://www.apple.com"];
804 titledURL._title = @"Apple";
805 auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]);
806 [simulatedItemProvider registerObject:titledURL visibility:UIItemProviderRepresentationOptionsVisibilityAll];
808 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
809 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]];
810 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
812 EXPECT_WK_STREQ("Apple", [webView stringByEvaluatingJavaScript:@"editor.querySelector('a').textContent"]);
813 EXPECT_WK_STREQ("https://www.apple.com/", [webView stringByEvaluatingJavaScript:@"editor.querySelector('a').href"]);
816 TEST(DataInteractionTests, ExternalSourceFileURL)
818 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
819 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
820 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
822 NSURL *URL = [NSURL URLWithString:@"file:///some/file/that/is/not/real"];
823 UIItemProvider *simulatedItemProvider = [UIItemProvider itemProviderWithURL:URL title:@""];
825 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
826 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider ]];
827 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
829 EXPECT_FALSE([[webView stringByEvaluatingJavaScript:@"!!editor.querySelector('a')"] boolValue]);
830 EXPECT_WK_STREQ("Hello world\nfile:///some/file/that/is/not/real", [webView stringByEvaluatingJavaScript:@"document.body.innerText"]);
833 TEST(DataInteractionTests, ExternalSourceOverrideDropFileUpload)
835 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
836 [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
838 auto simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]);
839 NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5);
840 [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData];
842 auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
843 NSData *firstHTMLData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding];
844 [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:firstHTMLData];
846 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
847 [dataInteractionSimulator setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session)
849 EXPECT_EQ(2UL, session.items.count);
850 UIDragItem *firstItem = session.items[0];
851 UIDragItem *secondItem = session.items[1];
852 EXPECT_TRUE([firstItem.itemProvider.registeredTypeIdentifiers isEqual:@[ (NSString *)kUTTypeJPEG ]]);
853 EXPECT_TRUE([secondItem.itemProvider.registeredTypeIdentifiers isEqual:@[ (NSString *)kUTTypeHTML ]]);
854 return @[ secondItem ];
856 [dataInteractionSimulator setExternalItemProviders:@[ simulatedImageItemProvider.get(), simulatedHTMLItemProvider.get() ]];
857 [dataInteractionSimulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)];
859 NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"];
860 EXPECT_WK_STREQ("text/html", outputValue.UTF8String);
863 TEST(DataInteractionTests, ExternalSourceOverrideDropInsertURL)
865 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
866 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
867 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
869 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
870 [dataInteractionSimulator setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session)
872 NSMutableArray<UIDragItem *> *allowedItems = [NSMutableArray array];
873 for (UIDragItem *item in session.items) {
874 if ([item.itemProvider.registeredTypeIdentifiers containsObject:(NSString *)kUTTypeURL])
875 [allowedItems addObject:item];
877 EXPECT_EQ(1UL, allowedItems.count);
881 auto firstItemProvider = adoptNS([[UIItemProvider alloc] init]);
882 [firstItemProvider registerObject:@"This is a string." visibility:UIItemProviderRepresentationOptionsVisibilityAll];
883 auto secondItemProvider = adoptNS([[UIItemProvider alloc] init]);
884 [secondItemProvider registerObject:[NSURL URLWithString:@"https://webkit.org/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll];
885 [dataInteractionSimulator setExternalItemProviders:@[ firstItemProvider.get(), secondItemProvider.get() ]];
886 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
888 EXPECT_WK_STREQ("https://webkit.org/", [webView stringByEvaluatingJavaScript:@"editor.textContent"]);
891 TEST(DataInteractionTests, OverrideDataInteractionOperation)
893 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
894 [webView synchronouslyLoadTestPageNamed:@"simple"];
896 auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]);
897 [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:[@"<body></body>" dataUsingEncoding:NSUTF8StringEncoding]];
899 __block bool finishedLoadingData = false;
900 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
901 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]];
902 [dataInteractionSimulator setOverrideDataInteractionOperationBlock:^NSUInteger(NSUInteger operation, id session)
904 EXPECT_EQ(0U, operation);
907 [dataInteractionSimulator setDataInteractionOperationCompletionBlock:^(BOOL handled, NSArray *itemProviders) {
908 EXPECT_FALSE(handled);
909 [itemProviders.firstObject loadDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML completionHandler:^(NSData *data, NSError *error) {
910 NSString *text = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
911 EXPECT_WK_STREQ("<body></body>", text.UTF8String);
912 EXPECT_FALSE(!!error);
913 finishedLoadingData = true;
916 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
917 TestWebKitAPI::Util::run(&finishedLoadingData);
920 TEST(DataInteractionTests, InjectedBundleOverridePerformTwoStepDrop)
922 WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"];
923 [configuration.processPool _setObject:@YES forBundleParameter:@"BundleOverridePerformTwoStepDrop"];
925 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]);
926 [webView loadTestPageNamed:@"autofocus-contenteditable"];
927 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
929 auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]);
930 [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock)
932 completionBlock([@"Hello world" dataUsingEncoding:NSUTF8StringEncoding], nil);
933 return [NSProgress discreteProgressWithTotalUnitCount:100];
936 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
937 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]];
938 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
940 EXPECT_EQ(0UL, [webView stringByEvaluatingJavaScript:@"editor.textContent"].length);
943 TEST(DataInteractionTests, InjectedBundleAllowPerformTwoStepDrop)
945 WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"];
946 [configuration.processPool _setObject:@NO forBundleParameter:@"BundleOverridePerformTwoStepDrop"];
948 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]);
949 [webView loadTestPageNamed:@"autofocus-contenteditable"];
950 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
952 auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]);
953 [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock)
955 completionBlock([@"Hello world" dataUsingEncoding:NSUTF8StringEncoding], nil);
956 return [NSProgress discreteProgressWithTotalUnitCount:100];
959 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
960 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]];
961 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
963 EXPECT_WK_STREQ("Hello world", [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String);
966 TEST(DataInteractionTests, InjectedBundleImageElementData)
968 WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"];
969 [configuration _setAttachmentElementEnabled:YES];
970 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]);
971 [webView synchronouslyLoadTestPageNamed:@"image-and-contenteditable"];
973 __block RetainPtr<NSString> injectedString;
974 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
975 [dataInteractionSimulator setConvertItemProvidersBlock:^NSArray *(UIItemProvider *itemProvider, NSArray *, NSDictionary *data)
977 injectedString = adoptNS([[NSString alloc] initWithData:data[InjectedBundlePasteboardDataType] encoding:NSUTF8StringEncoding]);
978 return @[ itemProvider ];
981 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 250)];
983 EXPECT_WK_STREQ("hello", [injectedString UTF8String]);
986 TEST(DataInteractionTests, InjectedBundleAttachmentElementData)
988 WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"];
989 [configuration _setAttachmentElementEnabled:YES];
990 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]);
991 [webView synchronouslyLoadTestPageNamed:@"attachment-element"];
993 __block RetainPtr<NSString> injectedString;
994 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
995 [dataInteractionSimulator setConvertItemProvidersBlock:^NSArray *(UIItemProvider *itemProvider, NSArray *, NSDictionary *data)
997 injectedString = adoptNS([[NSString alloc] initWithData:data[InjectedBundlePasteboardDataType] encoding:NSUTF8StringEncoding]);
998 return @[ itemProvider ];
1001 [dataInteractionSimulator runFrom:CGPointMake(50, 50) to:CGPointMake(50, 400)];
1003 EXPECT_WK_STREQ("hello", [injectedString UTF8String]);
1004 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"getSelection().isCollapsed"].boolValue);
1007 TEST(DataInteractionTests, LargeImageToTargetDiv)
1009 auto testWebViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
1010 [[testWebViewConfiguration preferences] _setLargeImageAsyncDecodingEnabled:NO];
1012 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:testWebViewConfiguration.get()]);
1013 [webView synchronouslyLoadTestPageNamed:@"div-and-large-image"];
1015 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
1016 [dataInteractionSimulator runFrom:CGPointMake(200, 400) to:CGPointMake(200, 150)];
1017 EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target.textContent"].UTF8String);
1018 checkTypeIdentifierAndIsNotOtherTypeIdentifier(dataInteractionSimulator.get(), (NSString *)kUTTypePNG, (NSString *)kUTTypeFileURL);
1019 checkEstimatedSize(dataInteractionSimulator.get(), { 2000, 2000 });
1022 TEST(DataInteractionTests, LinkWithEmptyHREF)
1024 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
1025 [webView synchronouslyLoadTestPageNamed:@"link-and-input"];
1026 [webView stringByEvaluatingJavaScript:@"document.querySelector('a').href = ''"];
1028 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
1029 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
1031 EXPECT_EQ(DataInteractionCancelled, [dataInteractionSimulator phase]);
1032 EXPECT_WK_STREQ("", [webView editorValue].UTF8String);
1035 TEST(DataInteractionTests, CancelledLiftDoesNotCauseSubsequentDragsToFail)
1037 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
1038 [webView synchronouslyLoadTestPageNamed:@"link-and-target-div"];
1040 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
1041 [dataInteractionSimulator setConvertItemProvidersBlock:^NSArray *(UIItemProvider *, NSArray *, NSDictionary *)
1045 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
1046 EXPECT_EQ(DataInteractionCancelled, [dataInteractionSimulator phase]);
1047 EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"target.textContent"]);
1048 NSString *outputText = [webView stringByEvaluatingJavaScript:@"output.textContent"];
1049 checkStringArraysAreEqual(@[@"dragstart", @"dragend"], [outputText componentsSeparatedByString:@" "]);
1051 [webView stringByEvaluatingJavaScript:@"output.innerHTML = ''"];
1052 [dataInteractionSimulator setConvertItemProvidersBlock:^NSArray *(UIItemProvider *itemProvider, NSArray *, NSDictionary *)
1054 return @[ itemProvider ];
1056 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
1057 EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target.textContent"]);
1058 [webView stringByEvaluatingJavaScript:@"output.textContent"];
1059 checkStringArraysAreEqual(@[@"dragstart", @"dragend"], [outputText componentsSeparatedByString:@" "]);
1062 TEST(DataInteractionTests, DoNotCrashWhenSelectionIsClearedInDragStart)
1064 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
1065 [webView synchronouslyLoadTestPageNamed:@"dragstart-clear-selection"];
1067 auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
1068 [simulator runFrom:CGPointMake(100, 100) to:CGPointMake(100, 100)];
1070 EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"paragraph.textContent"]);
1073 TEST(DataInteractionTests, CustomActionSheetPopover)
1075 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
1076 [webView synchronouslyLoadTestPageNamed:@"link-and-target-div"];
1078 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
1079 [dataInteractionSimulator setShouldEnsureUIApplication:YES];
1081 __block BOOL didInvokeCustomActionSheet = NO;
1082 [dataInteractionSimulator setShowCustomActionSheetBlock:^BOOL(_WKActivatedElementInfo *element)
1084 EXPECT_EQ(_WKActivatedElementTypeLink, element.type);
1085 EXPECT_WK_STREQ("Hello world", element.title.UTF8String);
1086 didInvokeCustomActionSheet = YES;
1089 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
1090 EXPECT_TRUE(didInvokeCustomActionSheet);
1091 EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target.textContent"].UTF8String);
1094 TEST(DataInteractionTests, UnresponsivePageDoesNotHangUI)
1096 _WKProcessPoolConfiguration *processPoolConfiguration = [[[_WKProcessPoolConfiguration alloc] init] autorelease];
1097 processPoolConfiguration.ignoreSynchronousMessagingTimeoutsForTesting = YES;
1099 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:[[[WKWebViewConfiguration alloc] init] autorelease] processPoolConfiguration:processPoolConfiguration]);
1100 [webView synchronouslyLoadTestPageNamed:@"simple"];
1101 [webView evaluateJavaScript:@"while(1);" completionHandler:nil];
1103 // The test passes if we can prepare for data interaction without timing out.
1104 [webView _simulatePrepareForDataInteractionSession:nil completion:^() { }];
1107 TEST(DataInteractionTests, WebItemProviderPasteboardLoading)
1109 static NSString *fastString = @"This data loads quickly";
1110 static NSString *slowString = @"This data loads slowly";
1112 WebItemProviderPasteboard *pasteboard = [WebItemProviderPasteboard sharedInstance];
1113 auto fastItem = adoptNS([[UIItemProvider alloc] init]);
1114 [fastItem registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock)
1116 completionBlock([fastString dataUsingEncoding:NSUTF8StringEncoding], nil);
1120 auto slowItem = adoptNS([[UIItemProvider alloc] init]);
1121 [slowItem registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock)
1124 completionBlock([slowString dataUsingEncoding:NSUTF8StringEncoding], nil);
1128 __block bool hasRunFirstCompletionBlock = false;
1129 pasteboard.itemProviders = @[ fastItem.get(), slowItem.get() ];
1130 [pasteboard doAfterLoadingProvidedContentIntoFileURLs:^(NSArray<NSURL *> *urls) {
1131 EXPECT_EQ(2UL, urls.count);
1132 auto firstString = adoptNS([[NSString alloc] initWithContentsOfURL:urls[0] encoding:NSUTF8StringEncoding error:nil]);
1133 auto secondString = adoptNS([[NSString alloc] initWithContentsOfURL:urls[1] encoding:NSUTF8StringEncoding error:nil]);
1134 EXPECT_WK_STREQ(fastString, [firstString UTF8String]);
1135 EXPECT_WK_STREQ(slowString, [secondString UTF8String]);
1136 hasRunFirstCompletionBlock = true;
1137 } synchronousTimeout:600];
1138 EXPECT_TRUE(hasRunFirstCompletionBlock);
1140 __block bool hasRunSecondCompletionBlock = false;
1141 [pasteboard doAfterLoadingProvidedContentIntoFileURLs:^(NSArray<NSURL *> *urls) {
1142 EXPECT_EQ(2UL, urls.count);
1143 auto firstString = adoptNS([[NSString alloc] initWithContentsOfURL:urls[0] encoding:NSUTF8StringEncoding error:nil]);
1144 auto secondString = adoptNS([[NSString alloc] initWithContentsOfURL:urls[1] encoding:NSUTF8StringEncoding error:nil]);
1145 EXPECT_WK_STREQ(fastString, [firstString UTF8String]);
1146 EXPECT_WK_STREQ(slowString, [secondString UTF8String]);
1147 hasRunSecondCompletionBlock = true;
1148 } synchronousTimeout:0];
1149 EXPECT_FALSE(hasRunSecondCompletionBlock);
1150 TestWebKitAPI::Util::run(&hasRunSecondCompletionBlock);
1153 TEST(DataInteractionTests, DoNotCrashWhenSelectionMovesOffscreenAfterDragStart)
1155 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
1156 [webView synchronouslyLoadTestPageNamed:@"dragstart-change-selection-offscreen"];
1158 auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
1159 [simulator runFrom:CGPointMake(100, 100) to:CGPointMake(100, 100)];
1161 EXPECT_WK_STREQ("FAR OFFSCREEN", [webView stringByEvaluatingJavaScript:@"getSelection().getRangeAt(0).toString()"]);
1164 } // namespace TestWebKitAPI
1166 #endif // ENABLE(DATA_INTERACTION)