blob: 9ae9fd382964323d4f50c9ef0ec154a552bc5985 [file] [log] [blame]
/*
* Copyright (C) 2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "config.h"
#import "EditingTestHarness.h"
#import "PlatformUtilities.h"
#import <WebKit/WKWebViewPrivateForTesting.h>
@implementation EditingTestHarness
- (instancetype)initWithWebView:(TestWKWebView *)webView
{
if (self = [super init]) {
_webView = webView;
[_webView setUIDelegate:self];
_editorStateHistory = adoptNS([[NSMutableArray alloc] init]);
}
return self;
}
- (void)dealloc
{
if ([_webView UIDelegate] == self)
[_webView setUIDelegate:nil];
[super dealloc];
}
- (TestWKWebView *)webView
{
return _webView.get();
}
- (NSDictionary *)latestEditorState
{
return self.editorStateHistory.lastObject;
}
- (NSArray<NSDictionary *> *)editorStateHistory
{
return _editorStateHistory.get();
}
- (void)insertParagraph
{
[self insertParagraphAndExpectEditorStateWith:nil];
}
- (void)insertText:(NSString *)text
{
[self insertText:text andExpectEditorStateWith:nil];
}
- (void)insertHTML:(NSString *)html
{
[self insertHTML:html andExpectEditorStateWith:nil];
}
- (void)selectAll
{
[self selectAllAndExpectEditorStateWith:nil];
}
- (void)deleteBackwards
{
[self deleteBackwardAndExpectEditorStateWith:nil];
}
- (void)moveBackward
{
[self moveBackwardAndExpectEditorStateWith:nil];
}
- (void)moveForward
{
[self moveForwardAndExpectEditorStateWith:nil];
}
- (void)insertText:(NSString *)text andExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
[self _execCommand:@"InsertText" argument:text expectEntries:entries];
}
- (void)insertHTML:(NSString *)html andExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
[self _execCommand:@"InsertHTML" argument:html expectEntries:entries];
}
- (void)selectAllAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
[self _execCommand:@"SelectAll" argument:nil expectEntries:entries];
}
- (void)moveBackwardAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
[self _execCommand:@"MoveBackward" argument:nil expectEntries:entries];
}
- (void)moveWordBackwardAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
[self _execCommand:@"MoveWordBackward" argument:nil expectEntries:entries];
}
- (void)moveForwardAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
[self _execCommand:@"MoveForward" argument:nil expectEntries:entries];
}
- (void)toggleBold
{
[self _execCommand:@"ToggleBold" argument:nil expectEntries:nil];
}
- (void)toggleItalic
{
[self _execCommand:@"ToggleItalic" argument:nil expectEntries:nil];
}
- (void)toggleUnderline
{
[self _execCommand:@"ToggleUnderline" argument:nil expectEntries:nil];
}
- (void)setForegroundColor:(NSString *)colorAsString
{
[self _execCommand:@"ForeColor" argument:colorAsString expectEntries:nil];
}
- (void)alignJustifiedAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
[self _execCommand:@"AlignJustified" argument:nil expectEntries:entries];
}
- (void)alignLeftAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
[self _execCommand:@"AlignLeft" argument:nil expectEntries:entries];
}
- (void)alignCenterAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
[self _execCommand:@"AlignCenter" argument:nil expectEntries:entries];
}
- (void)alignRightAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
[self _execCommand:@"AlignRight" argument:nil expectEntries:entries];
}
- (void)insertParagraphAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
[self _execCommand:@"InsertParagraph" argument:nil expectEntries:entries];
}
- (void)deleteBackwardAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
[self _execCommand:@"DeleteBackward" argument:nil expectEntries:entries];
}
- (void)_execCommand:(NSString *)command argument:(NSString *)argument expectEntries:(NSDictionary<NSString *, id> *)entries
{
__block BOOL result = false;
__block bool done = false;
[_webView _executeEditCommand:command argument:argument completion:^(BOOL success) {
result = success;
done = true;
}];
TestWebKitAPI::Util::run(&done);
EXPECT_TRUE(result);
if (!result)
NSLog(@"Failed to execute editing command: ('%@', '%@')", command, argument ?: @"");
const NSTimeInterval loggingTimeout = 3;
auto startTime = retainPtr([NSDate date]);
BOOL hasLoggedWarning = NO;
BOOL containsEntries;
do {
[_webView waitForNextPresentationUpdate];
containsEntries = [self latestEditorStateContains:entries];
if (!hasLoggedWarning && [[NSDate date] timeIntervalSinceDate:startTime.get()] > loggingTimeout) {
NSLog(@"Expected %@ to contain %@", self.latestEditorState, entries);
hasLoggedWarning = YES;
}
} while (!containsEntries);
}
- (BOOL)latestEditorStateContains:(NSDictionary<NSString *, id> *)entries
{
NSDictionary *latestEditorState = self.latestEditorState;
for (NSString *key in entries) {
if (![latestEditorState[key] isEqual:entries[key]])
return NO;
}
return latestEditorState.count || !entries.count;
}
#pragma mark - WKUIDelegatePrivate
- (void)_webView:(WKWebView *)webView editorStateDidChange:(NSDictionary *)editorState
{
if (![editorState[@"post-layout-data"] boolValue])
return;
if (![self.latestEditorState isEqualToDictionary:editorState])
[_editorStateHistory addObject:editorState];
}
@end