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, DISABLED_ExternalSourceBoldSystemAttributedStringToContentEditable)
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, ExternalSourceColoredAttributedStringToContentEditable)
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 NSDictionary *textAttributes = @{ NSForegroundColorAttributeName: [UIColor redColor] };
712 NSAttributedString *richText = [[NSAttributedString alloc] initWithString:@"This is a test" attributes:textAttributes];
713 auto itemProvider = adoptNS([[UIItemProvider alloc] initWithObject:richText]);
714 [dataInteractionSimulator setExternalItemProviders:@[ itemProvider.get() ]];
715 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
717 EXPECT_WK_STREQ("rgb(255, 0, 0)", [webView stringByEvaluatingJavaScript:@"getComputedStyle(document.querySelector('p')).color"]);
718 EXPECT_WK_STREQ("This is a test", [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String);
721 TEST(DataInteractionTests, ExternalSourceMultipleURLsToContentEditable)
723 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
724 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
725 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
727 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
728 auto firstItem = adoptNS([[UIItemProvider alloc] init]);
729 [firstItem registerObject:[NSURL URLWithString:@"https://www.apple.com/iphone/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll];
730 auto secondItem = adoptNS([[UIItemProvider alloc] init]);
731 [secondItem registerObject:[NSURL URLWithString:@"https://www.apple.com/mac/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll];
732 auto thirdItem = adoptNS([[UIItemProvider alloc] init]);
733 [thirdItem registerObject:[NSURL URLWithString:@"https://webkit.org/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll];
734 [dataInteractionSimulator setExternalItemProviders:@[ firstItem.get(), secondItem.get(), thirdItem.get() ]];
735 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
737 NSArray *separatedLinks = [[webView stringByEvaluatingJavaScript:@"editor.textContent"] componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
738 EXPECT_EQ(3UL, separatedLinks.count);
739 EXPECT_WK_STREQ("https://www.apple.com/iphone/", separatedLinks[0]);
740 EXPECT_WK_STREQ("https://www.apple.com/mac/", separatedLinks[1]);
741 EXPECT_WK_STREQ("https://webkit.org/", separatedLinks[2]);
744 TEST(DataInteractionTests, RespectsExternalSourceFidelityRankings)
746 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
747 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
748 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
750 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
752 // Here, our source item provider vends two representations: plain text, and then an image. If we don't respect the
753 // fidelity order requested by the source, we'll end up assuming that the image is a higher fidelity representation
754 // than the plain text, and erroneously insert the image. If we respect source fidelities, we'll insert text rather
756 auto simulatedItemProviderWithTextFirst = adoptNS([[UIItemProvider alloc] init]);
757 [simulatedItemProviderWithTextFirst registerObject:@"Hello world" visibility:UIItemProviderRepresentationOptionsVisibilityAll];
758 [simulatedItemProviderWithTextFirst registerObject:testIconImage() visibility:UIItemProviderRepresentationOptionsVisibilityAll];
759 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProviderWithTextFirst.get() ]];
761 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
762 EXPECT_WK_STREQ("Hello world", [webView stringByEvaluatingJavaScript:@"editor.textContent"]);
763 EXPECT_FALSE([webView editorContainsImageElement]);
764 [webView stringByEvaluatingJavaScript:@"editor.innerHTML = ''"];
766 // Now we register the item providers in reverse, and expect the image to be inserted instead of text.
767 auto simulatedItemProviderWithImageFirst = adoptNS([[UIItemProvider alloc] init]);
768 [simulatedItemProviderWithImageFirst registerObject:testIconImage() visibility:UIItemProviderRepresentationOptionsVisibilityAll];
769 [simulatedItemProviderWithImageFirst registerObject:@"Hello world" visibility:UIItemProviderRepresentationOptionsVisibilityAll];
770 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProviderWithImageFirst.get() ]];
772 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
773 EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"editor.textContent"]);
774 EXPECT_TRUE([webView editorContainsImageElement]);
777 TEST(DataInteractionTests, ExternalSourceUTF8PlainTextOnly)
779 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
780 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
782 NSString *textPayload = @"Ceci n'est pas une string";
783 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
784 auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]);
785 [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock)
787 completionBlock([textPayload dataUsingEncoding:NSUTF8StringEncoding], nil);
788 return [NSProgress discreteProgressWithTotalUnitCount:100];
790 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]];
791 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
792 EXPECT_WK_STREQ(textPayload.UTF8String, [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String);
793 checkSelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 1936, 227) ], [dataInteractionSimulator finalSelectionRects]);
796 TEST(DataInteractionTests, ExternalSourceJPEGOnly)
798 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
799 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
801 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
802 auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]);
803 [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypeJPEG options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock)
805 completionBlock(UIImageJPEGRepresentation(testIconImage(), 0.5), nil);
806 return [NSProgress discreteProgressWithTotalUnitCount:100];
808 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]];
809 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
810 EXPECT_TRUE([webView editorContainsImageElement]);
811 checkSelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 215, 174) ], [dataInteractionSimulator finalSelectionRects]);
814 TEST(DataInteractionTests, ExternalSourceTitledNSURL)
816 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
817 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
818 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
820 NSURL *titledURL = [NSURL URLWithString:@"https://www.apple.com"];
821 titledURL._title = @"Apple";
822 auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]);
823 [simulatedItemProvider registerObject:titledURL visibility:UIItemProviderRepresentationOptionsVisibilityAll];
825 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
826 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]];
827 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
829 EXPECT_WK_STREQ("Apple", [webView stringByEvaluatingJavaScript:@"editor.querySelector('a').textContent"]);
830 EXPECT_WK_STREQ("https://www.apple.com/", [webView stringByEvaluatingJavaScript:@"editor.querySelector('a').href"]);
833 TEST(DataInteractionTests, ExternalSourceFileURL)
835 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
836 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
837 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
839 NSURL *URL = [NSURL URLWithString:@"file:///some/file/that/is/not/real"];
840 UIItemProvider *simulatedItemProvider = [UIItemProvider itemProviderWithURL:URL title:@""];
842 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
843 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider ]];
844 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
846 EXPECT_FALSE([[webView stringByEvaluatingJavaScript:@"!!editor.querySelector('a')"] boolValue]);
847 EXPECT_WK_STREQ("Hello world\nfile:///some/file/that/is/not/real", [webView stringByEvaluatingJavaScript:@"document.body.innerText"]);
850 TEST(DataInteractionTests, ExternalSourceOverrideDropFileUpload)
852 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
853 [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
855 auto simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]);
856 NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5);
857 [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData];
859 auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
860 NSData *firstHTMLData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding];
861 [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:firstHTMLData];
863 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
864 [dataInteractionSimulator setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session)
866 EXPECT_EQ(2UL, session.items.count);
867 UIDragItem *firstItem = session.items[0];
868 UIDragItem *secondItem = session.items[1];
869 EXPECT_TRUE([firstItem.itemProvider.registeredTypeIdentifiers isEqual:@[ (NSString *)kUTTypeJPEG ]]);
870 EXPECT_TRUE([secondItem.itemProvider.registeredTypeIdentifiers isEqual:@[ (NSString *)kUTTypeHTML ]]);
871 return @[ secondItem ];
873 [dataInteractionSimulator setExternalItemProviders:@[ simulatedImageItemProvider.get(), simulatedHTMLItemProvider.get() ]];
874 [dataInteractionSimulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)];
876 NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"];
877 EXPECT_WK_STREQ("text/html", outputValue.UTF8String);
880 TEST(DataInteractionTests, ExternalSourceOverrideDropInsertURL)
882 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
883 [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
884 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
886 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
887 [dataInteractionSimulator setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session)
889 NSMutableArray<UIDragItem *> *allowedItems = [NSMutableArray array];
890 for (UIDragItem *item in session.items) {
891 if ([item.itemProvider.registeredTypeIdentifiers containsObject:(NSString *)kUTTypeURL])
892 [allowedItems addObject:item];
894 EXPECT_EQ(1UL, allowedItems.count);
898 auto firstItemProvider = adoptNS([[UIItemProvider alloc] init]);
899 [firstItemProvider registerObject:@"This is a string." visibility:UIItemProviderRepresentationOptionsVisibilityAll];
900 auto secondItemProvider = adoptNS([[UIItemProvider alloc] init]);
901 [secondItemProvider registerObject:[NSURL URLWithString:@"https://webkit.org/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll];
902 [dataInteractionSimulator setExternalItemProviders:@[ firstItemProvider.get(), secondItemProvider.get() ]];
903 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
905 EXPECT_WK_STREQ("https://webkit.org/", [webView stringByEvaluatingJavaScript:@"editor.textContent"]);
908 TEST(DataInteractionTests, OverrideDataInteractionOperation)
910 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
911 [webView synchronouslyLoadTestPageNamed:@"simple"];
913 auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]);
914 [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:[@"<body></body>" dataUsingEncoding:NSUTF8StringEncoding]];
916 __block bool finishedLoadingData = false;
917 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
918 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]];
919 [dataInteractionSimulator setOverrideDataInteractionOperationBlock:^NSUInteger(NSUInteger operation, id session)
921 EXPECT_EQ(0U, operation);
924 [dataInteractionSimulator setDataInteractionOperationCompletionBlock:^(BOOL handled, NSArray *itemProviders) {
925 EXPECT_FALSE(handled);
926 [itemProviders.firstObject loadDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML completionHandler:^(NSData *data, NSError *error) {
927 NSString *text = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
928 EXPECT_WK_STREQ("<body></body>", text.UTF8String);
929 EXPECT_FALSE(!!error);
930 finishedLoadingData = true;
933 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
934 TestWebKitAPI::Util::run(&finishedLoadingData);
937 TEST(DataInteractionTests, InjectedBundleOverridePerformTwoStepDrop)
939 WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"];
940 [configuration.processPool _setObject:@YES forBundleParameter:@"BundleOverridePerformTwoStepDrop"];
942 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]);
943 [webView loadTestPageNamed:@"autofocus-contenteditable"];
944 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
946 auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]);
947 [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock)
949 completionBlock([@"Hello world" dataUsingEncoding:NSUTF8StringEncoding], nil);
950 return [NSProgress discreteProgressWithTotalUnitCount:100];
953 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
954 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]];
955 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
957 EXPECT_EQ(0UL, [webView stringByEvaluatingJavaScript:@"editor.textContent"].length);
960 TEST(DataInteractionTests, InjectedBundleAllowPerformTwoStepDrop)
962 WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"];
963 [configuration.processPool _setObject:@NO forBundleParameter:@"BundleOverridePerformTwoStepDrop"];
965 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]);
966 [webView loadTestPageNamed:@"autofocus-contenteditable"];
967 [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
969 auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]);
970 [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock)
972 completionBlock([@"Hello world" dataUsingEncoding:NSUTF8StringEncoding], nil);
973 return [NSProgress discreteProgressWithTotalUnitCount:100];
976 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
977 [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]];
978 [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
980 EXPECT_WK_STREQ("Hello world", [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String);
983 TEST(DataInteractionTests, InjectedBundleImageElementData)
985 WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"];
986 [configuration _setAttachmentElementEnabled:YES];
987 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]);
988 [webView synchronouslyLoadTestPageNamed:@"image-and-contenteditable"];
990 __block RetainPtr<NSString> injectedString;
991 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
992 [dataInteractionSimulator setConvertItemProvidersBlock:^NSArray *(UIItemProvider *itemProvider, NSArray *, NSDictionary *data)
994 injectedString = adoptNS([[NSString alloc] initWithData:data[InjectedBundlePasteboardDataType] encoding:NSUTF8StringEncoding]);
995 return @[ itemProvider ];
998 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 250)];
1000 EXPECT_WK_STREQ("hello", [injectedString UTF8String]);
1003 TEST(DataInteractionTests, InjectedBundleAttachmentElementData)
1005 WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"];
1006 [configuration _setAttachmentElementEnabled:YES];
1007 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]);
1008 [webView synchronouslyLoadTestPageNamed:@"attachment-element"];
1010 __block RetainPtr<NSString> injectedString;
1011 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
1012 [dataInteractionSimulator setConvertItemProvidersBlock:^NSArray *(UIItemProvider *itemProvider, NSArray *, NSDictionary *data)
1014 injectedString = adoptNS([[NSString alloc] initWithData:data[InjectedBundlePasteboardDataType] encoding:NSUTF8StringEncoding]);
1015 return @[ itemProvider ];
1018 [dataInteractionSimulator runFrom:CGPointMake(50, 50) to:CGPointMake(50, 400)];
1020 EXPECT_WK_STREQ("hello", [injectedString UTF8String]);
1021 EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"getSelection().isCollapsed"].boolValue);
1024 TEST(DataInteractionTests, LargeImageToTargetDiv)
1026 auto testWebViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
1027 [[testWebViewConfiguration preferences] _setLargeImageAsyncDecodingEnabled:NO];
1029 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:testWebViewConfiguration.get()]);
1030 [webView synchronouslyLoadTestPageNamed:@"div-and-large-image"];
1032 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
1033 [dataInteractionSimulator runFrom:CGPointMake(200, 400) to:CGPointMake(200, 150)];
1034 EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target.textContent"].UTF8String);
1035 checkTypeIdentifierAndIsNotOtherTypeIdentifier(dataInteractionSimulator.get(), (NSString *)kUTTypePNG, (NSString *)kUTTypeFileURL);
1036 checkEstimatedSize(dataInteractionSimulator.get(), { 2000, 2000 });
1039 TEST(DataInteractionTests, LinkWithEmptyHREF)
1041 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
1042 [webView synchronouslyLoadTestPageNamed:@"link-and-input"];
1043 [webView stringByEvaluatingJavaScript:@"document.querySelector('a').href = ''"];
1045 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
1046 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
1048 EXPECT_EQ(DataInteractionCancelled, [dataInteractionSimulator phase]);
1049 EXPECT_WK_STREQ("", [webView editorValue].UTF8String);
1052 TEST(DataInteractionTests, CancelledLiftDoesNotCauseSubsequentDragsToFail)
1054 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
1055 [webView synchronouslyLoadTestPageNamed:@"link-and-target-div"];
1057 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
1058 [dataInteractionSimulator setConvertItemProvidersBlock:^NSArray *(UIItemProvider *, NSArray *, NSDictionary *)
1062 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
1063 EXPECT_EQ(DataInteractionCancelled, [dataInteractionSimulator phase]);
1064 EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"target.textContent"]);
1065 NSString *outputText = [webView stringByEvaluatingJavaScript:@"output.textContent"];
1066 checkStringArraysAreEqual(@[@"dragstart", @"dragend"], [outputText componentsSeparatedByString:@" "]);
1068 [webView stringByEvaluatingJavaScript:@"output.innerHTML = ''"];
1069 [dataInteractionSimulator setConvertItemProvidersBlock:^NSArray *(UIItemProvider *itemProvider, NSArray *, NSDictionary *)
1071 return @[ itemProvider ];
1073 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
1074 EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target.textContent"]);
1075 [webView stringByEvaluatingJavaScript:@"output.textContent"];
1076 checkStringArraysAreEqual(@[@"dragstart", @"dragend"], [outputText componentsSeparatedByString:@" "]);
1079 TEST(DataInteractionTests, DoNotCrashWhenSelectionIsClearedInDragStart)
1081 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
1082 [webView synchronouslyLoadTestPageNamed:@"dragstart-clear-selection"];
1084 auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
1085 [simulator runFrom:CGPointMake(100, 100) to:CGPointMake(100, 100)];
1087 EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"paragraph.textContent"]);
1090 TEST(DataInteractionTests, CustomActionSheetPopover)
1092 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
1093 [webView synchronouslyLoadTestPageNamed:@"link-and-target-div"];
1095 auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
1096 [dataInteractionSimulator setShouldEnsureUIApplication:YES];
1098 __block BOOL didInvokeCustomActionSheet = NO;
1099 [dataInteractionSimulator setShowCustomActionSheetBlock:^BOOL(_WKActivatedElementInfo *element)
1101 EXPECT_EQ(_WKActivatedElementTypeLink, element.type);
1102 EXPECT_WK_STREQ("Hello world", element.title.UTF8String);
1103 didInvokeCustomActionSheet = YES;
1106 [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
1107 EXPECT_TRUE(didInvokeCustomActionSheet);
1108 EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target.textContent"].UTF8String);
1111 TEST(DataInteractionTests, UnresponsivePageDoesNotHangUI)
1113 _WKProcessPoolConfiguration *processPoolConfiguration = [[[_WKProcessPoolConfiguration alloc] init] autorelease];
1114 processPoolConfiguration.ignoreSynchronousMessagingTimeoutsForTesting = YES;
1116 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:[[[WKWebViewConfiguration alloc] init] autorelease] processPoolConfiguration:processPoolConfiguration]);
1117 [webView synchronouslyLoadTestPageNamed:@"simple"];
1118 [webView evaluateJavaScript:@"while(1);" completionHandler:nil];
1120 // The test passes if we can prepare for data interaction without timing out.
1121 [webView _simulatePrepareForDataInteractionSession:nil completion:^() { }];
1124 TEST(DataInteractionTests, WebItemProviderPasteboardLoading)
1126 static NSString *fastString = @"This data loads quickly";
1127 static NSString *slowString = @"This data loads slowly";
1129 WebItemProviderPasteboard *pasteboard = [WebItemProviderPasteboard sharedInstance];
1130 auto fastItem = adoptNS([[UIItemProvider alloc] init]);
1131 [fastItem registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock)
1133 completionBlock([fastString dataUsingEncoding:NSUTF8StringEncoding], nil);
1137 auto slowItem = adoptNS([[UIItemProvider alloc] init]);
1138 [slowItem registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock)
1141 completionBlock([slowString dataUsingEncoding:NSUTF8StringEncoding], nil);
1145 __block bool hasRunFirstCompletionBlock = false;
1146 pasteboard.itemProviders = @[ fastItem.get(), slowItem.get() ];
1147 [pasteboard doAfterLoadingProvidedContentIntoFileURLs:^(NSArray<NSURL *> *urls) {
1148 EXPECT_EQ(2UL, urls.count);
1149 auto firstString = adoptNS([[NSString alloc] initWithContentsOfURL:urls[0] encoding:NSUTF8StringEncoding error:nil]);
1150 auto secondString = adoptNS([[NSString alloc] initWithContentsOfURL:urls[1] encoding:NSUTF8StringEncoding error:nil]);
1151 EXPECT_WK_STREQ(fastString, [firstString UTF8String]);
1152 EXPECT_WK_STREQ(slowString, [secondString UTF8String]);
1153 hasRunFirstCompletionBlock = true;
1154 } synchronousTimeout:600];
1155 EXPECT_TRUE(hasRunFirstCompletionBlock);
1157 __block bool hasRunSecondCompletionBlock = false;
1158 [pasteboard doAfterLoadingProvidedContentIntoFileURLs:^(NSArray<NSURL *> *urls) {
1159 EXPECT_EQ(2UL, urls.count);
1160 auto firstString = adoptNS([[NSString alloc] initWithContentsOfURL:urls[0] encoding:NSUTF8StringEncoding error:nil]);
1161 auto secondString = adoptNS([[NSString alloc] initWithContentsOfURL:urls[1] encoding:NSUTF8StringEncoding error:nil]);
1162 EXPECT_WK_STREQ(fastString, [firstString UTF8String]);
1163 EXPECT_WK_STREQ(slowString, [secondString UTF8String]);
1164 hasRunSecondCompletionBlock = true;
1165 } synchronousTimeout:0];
1166 EXPECT_FALSE(hasRunSecondCompletionBlock);
1167 TestWebKitAPI::Util::run(&hasRunSecondCompletionBlock);
1170 TEST(DataInteractionTests, DoNotCrashWhenSelectionMovesOffscreenAfterDragStart)
1172 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
1173 [webView synchronouslyLoadTestPageNamed:@"dragstart-change-selection-offscreen"];
1175 auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
1176 [simulator runFrom:CGPointMake(100, 100) to:CGPointMake(100, 100)];
1178 EXPECT_WK_STREQ("FAR OFFSCREEN", [webView stringByEvaluatingJavaScript:@"getSelection().getRangeAt(0).toString()"]);
1181 } // namespace TestWebKitAPI
1183 #endif // ENABLE(DATA_INTERACTION)