appium-webdriveragent 8.7.6 → 8.7.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## [8.7.8](https://github.com/appium/WebDriverAgent/compare/v8.7.7...v8.7.8) (2024-07-18)
2
+
3
+ ### Bug Fixes
4
+
5
+ * do nothing for an empty array in w3c actions ([#919](https://github.com/appium/WebDriverAgent/issues/919)) ([9e70ec1](https://github.com/appium/WebDriverAgent/commit/9e70ec1dbec1d1844278a58297a5b956ebaeb7fc))
6
+
7
+ ## [8.7.7](https://github.com/appium/WebDriverAgent/compare/v8.7.6...v8.7.7) (2024-07-18)
8
+
9
+ ### Bug Fixes
10
+
11
+ * Pass-through modifier keys ([#918](https://github.com/appium/WebDriverAgent/issues/918)) ([29d0e5c](https://github.com/appium/WebDriverAgent/commit/29d0e5cb2a19809e1babb06e5adaa49b43c754a5))
12
+
1
13
  ## [8.7.6](https://github.com/appium/WebDriverAgent/compare/v8.7.5...v8.7.6) (2024-07-02)
2
14
 
3
15
  ### Miscellaneous Chores
@@ -15,11 +15,11 @@
15
15
  <key>CFBundlePackageType</key>
16
16
  <string>FMWK</string>
17
17
  <key>CFBundleShortVersionString</key>
18
- <string>8.7.6</string>
18
+ <string>8.7.8</string>
19
19
  <key>CFBundleSignature</key>
20
20
  <string>????</string>
21
21
  <key>CFBundleVersion</key>
22
- <string>8.7.6</string>
22
+ <string>8.7.8</string>
23
23
  <key>NSPrincipalClass</key>
24
24
  <string/>
25
25
  </dict>
@@ -30,19 +30,14 @@ NSString *_Nullable FBRequireValue(NSDictionary<NSString *, id> *actionItem, NSE
30
30
  */
31
31
  NSNumber *_Nullable FBOptDuration(NSDictionary<NSString *, id> *actionItem, NSNumber *_Nullable defaultValue, NSError **error);
32
32
 
33
- /**
34
- * Checks whether the given key action value is a W3C meta modifier
35
- * @param value key action value
36
- * @returns YES if the value is a meta modifier
37
- */
38
- BOOL FBIsMetaModifier(NSString *value);
39
-
40
33
  /**
41
34
  * Maps W3C meta modifier to XCUITest compatible-one
35
+ * See https://w3c.github.io/webdriver/#keyboard-actions
42
36
  *
43
37
  * @param value key action value
44
- * @returns the mapped modifier value or 0 in case of failure
38
+ * @returns the mapped modifier value or the same input character
39
+ * if no mapped value could be found for it.
45
40
  */
46
- NSUInteger FBToMetaModifier(NSString *value);
41
+ NSString * FBMapIfSpecialCharacter(NSString *value);
47
42
 
48
43
  NS_ASSUME_NONNULL_END
@@ -53,32 +53,68 @@ NSNumber *_Nullable FBOptDuration(NSDictionary<NSString *, id> *actionItem, NSNu
53
53
  return durationObj;
54
54
  }
55
55
 
56
- BOOL FBIsMetaModifier(NSString *value)
56
+ NSString *FBMapIfSpecialCharacter(NSString *value)
57
57
  {
58
- unichar charCode = [value characterAtIndex:0];
59
- return charCode >= 0xE000 && charCode <= 0xF8FF;
60
- }
61
-
62
- NSUInteger FBToMetaModifier(NSString *value)
63
- {
64
- if (!FBIsMetaModifier(value)) {
65
- return 0;
58
+ if (0 == [value length]) {
59
+ return value;
66
60
  }
67
61
 
68
62
  unichar charCode = [value characterAtIndex:0];
69
63
  switch (charCode) {
70
64
  case 0xE000:
71
- return XCUIKeyModifierNone;
72
- case 0xE03D:
73
- return XCUIKeyModifierCommand;
74
- case 0xE009:
75
- return XCUIKeyModifierControl;
76
- case 0xE00A:
77
- return XCUIKeyModifierOption;
78
- case 0xE008:
79
- return XCUIKeyModifierShift;
65
+ return @"";
66
+ case 0xE003:
67
+ return [NSString stringWithFormat:@"%C", 0x0008];
68
+ case 0xE004:
69
+ return [NSString stringWithFormat:@"%C", 0x0009];
70
+ case 0xE006:
71
+ return [NSString stringWithFormat:@"%C", 0x000D];
72
+ case 0xE007:
73
+ return [NSString stringWithFormat:@"%C", 0x000A];
74
+ case 0xE00C:
75
+ return [NSString stringWithFormat:@"%C", 0x001B];
76
+ case 0xE00D:
77
+ case 0xE05D:
78
+ return @" ";
79
+ case 0xE017:
80
+ return [NSString stringWithFormat:@"%C", 0x007F];
81
+ case 0xE018:
82
+ return @";";
83
+ case 0xE019:
84
+ return @"=";
85
+ case 0xE01A:
86
+ return @"0";
87
+ case 0xE01B:
88
+ return @"1";
89
+ case 0xE01C:
90
+ return @"2";
91
+ case 0xE01D:
92
+ return @"3";
93
+ case 0xE01E:
94
+ return @"4";
95
+ case 0xE01F:
96
+ return @"5";
97
+ case 0xE020:
98
+ return @"6";
99
+ case 0xE021:
100
+ return @"7";
101
+ case 0xE022:
102
+ return @"8";
103
+ case 0xE023:
104
+ return @"9";
105
+ case 0xE024:
106
+ return @"*";
107
+ case 0xE025:
108
+ return @"+";
109
+ case 0xE026:
110
+ return @",";
111
+ case 0xE027:
112
+ return @"-";
113
+ case 0xE028:
114
+ return @".";
115
+ case 0xE029:
116
+ return @"/";
80
117
  default:
81
- [FBLogger logFmt:@"Skipping the unsupported meta modifier with code %@", @(charCode)];
82
- return 0;
118
+ return charCode >= 0xE000 && charCode <= 0xE05D ? @"" : value;
83
119
  }
84
120
  }
@@ -410,17 +410,12 @@ static NSString *const FB_KEY_ACTIONS = @"actions";
410
410
  currentItemIndex:(NSUInteger)currentItemIndex
411
411
  {
412
412
  NSInteger balance = 1;
413
- BOOL isSelfMetaModifier = FBIsMetaModifier(self.value);
414
413
  for (NSInteger index = currentItemIndex - 1; index >= 0; index--) {
415
414
  FBW3CKeyItem *item = [allItems objectAtIndex:index];
416
415
  BOOL isKeyDown = [item isKindOfClass:FBKeyDownItem.class];
417
416
  BOOL isKeyUp = !isKeyDown && [item isKindOfClass:FBKeyUpItem.class];
418
417
  if (!isKeyUp && !isKeyDown) {
419
- if (isSelfMetaModifier) {
420
- continue;
421
- } else {
422
- break;
423
- }
418
+ break;
424
419
  }
425
420
 
426
421
  NSString *value = [item performSelector:@selector(value)];
@@ -434,32 +429,6 @@ static NSString *const FB_KEY_ACTIONS = @"actions";
434
429
  return 0 == balance;
435
430
  }
436
431
 
437
- - (NSUInteger)collectModifersWithItems:(NSArray *)allItems
438
- currentItemIndex:(NSUInteger)currentItemIndex
439
- {
440
- NSUInteger modifiers = 0;
441
- for (NSUInteger index = 0; index < currentItemIndex; index++) {
442
- FBW3CKeyItem *item = [allItems objectAtIndex:index];
443
- BOOL isKeyDown = [item isKindOfClass:FBKeyDownItem.class];
444
- BOOL isKeyUp = !isKeyDown && [item isKindOfClass:FBKeyUpItem.class];
445
- if (!isKeyUp && !isKeyDown) {
446
- continue;
447
- }
448
-
449
- NSString *value = [item performSelector:@selector(value)];
450
- NSUInteger modifier = FBToMetaModifier(value);
451
- if (modifier > 0) {
452
- if (isKeyDown) {
453
- modifiers |= modifier;
454
- } else if (item.offset < self.offset) {
455
- // only cancel the modifier if it is not in the same group
456
- modifiers &= ~modifier;
457
- }
458
- }
459
- }
460
- return modifiers;
461
- }
462
-
463
432
  - (NSString *)collectTextWithItems:(NSArray *)allItems
464
433
  currentItemIndex:(NSUInteger)currentItemIndex
465
434
  {
@@ -473,12 +442,8 @@ static NSString *const FB_KEY_ACTIONS = @"actions";
473
442
  }
474
443
 
475
444
  NSString *value = [item performSelector:@selector(value)];
476
- if (FBIsMetaModifier(value)) {
477
- continue;
478
- }
479
-
480
445
  if (isKeyUp) {
481
- [result addObject:value];
446
+ [result addObject:FBMapIfSpecialCharacter(value)];
482
447
  }
483
448
  }
484
449
  return [result.reverseObjectEnumerator.allObjects componentsJoinedByString:@""];
@@ -497,10 +462,6 @@ static NSString *const FB_KEY_ACTIONS = @"actions";
497
462
  return nil;
498
463
  }
499
464
 
500
- if (FBIsMetaModifier(self.value)) {
501
- return @[];
502
- }
503
-
504
465
  BOOL isLastKeyUpInGroup = currentItemIndex == allItems.count - 1
505
466
  || [[allItems objectAtIndex:currentItemIndex + 1] isKindOfClass:FBKeyPauseItem.class];
506
467
  if (!isLastKeyUpInGroup) {
@@ -510,10 +471,6 @@ static NSString *const FB_KEY_ACTIONS = @"actions";
510
471
  NSString *text = [self collectTextWithItems:allItems currentItemIndex:currentItemIndex];
511
472
  NSTimeInterval offset = FBMillisToSeconds(self.offset);
512
473
  XCPointerEventPath *resultPath = [[XCPointerEventPath alloc] initForTextInput];
513
- // TODO: Figure out how meta modifiers could be applied
514
- // TODO: The current approach throws zero division error on execution
515
- // NSUInteger modifiers = [self collectModifersWithItems:allItems currentItemIndex:currentItemIndex];
516
- // [resultPath setModifiers:modifiers mergeWithCurrentModifierFlags:NO atOffset:0];
517
474
  [resultPath typeText:text
518
475
  atOffset:offset
519
476
  typingSpeed:FBConfiguration.maxTypingFrequency
@@ -555,17 +512,12 @@ static NSString *const FB_KEY_ACTIONS = @"actions";
555
512
  currentItemIndex:(NSUInteger)currentItemIndex
556
513
  {
557
514
  NSInteger balance = 1;
558
- BOOL isSelfMetaModifier = FBIsMetaModifier(self.value);
559
515
  for (NSUInteger index = currentItemIndex + 1; index < allItems.count; index++) {
560
516
  FBW3CKeyItem *item = [allItems objectAtIndex:index];
561
517
  BOOL isKeyDown = [item isKindOfClass:FBKeyDownItem.class];
562
518
  BOOL isKeyUp = !isKeyDown && [item isKindOfClass:FBKeyUpItem.class];
563
519
  if (!isKeyUp && !isKeyDown) {
564
- if (isSelfMetaModifier) {
565
- continue;
566
- } else {
567
- break;
568
- }
520
+ break;
569
521
  }
570
522
 
571
523
  NSString *value = [item performSelector:@selector(value)];
@@ -740,14 +692,6 @@ static NSString *const FB_KEY_ACTIONS = @"actions";
740
692
  });
741
693
 
742
694
  NSArray<NSDictionary<NSString *, id> *> *actionItems = [actionDescription objectForKey:FB_KEY_ACTIONS];
743
- if (nil == actionItems || 0 == actionItems.count) {
744
- NSString *description = [NSString stringWithFormat:@"It is mandatory to have at least one item defined for each action. Action with id '%@' contains none", actionId];
745
- if (error) {
746
- *error = [[FBErrorBuilder.builder withDescription:description] build];
747
- }
748
- return nil;
749
- }
750
-
751
695
  FBW3CKeyItemsChain *chain = [[FBW3CKeyItemsChain alloc] init];
752
696
  NSArray<NSDictionary<NSString *, id> *> *processedItems = [self preprocessedActionItemsWith:actionItems];
753
697
  for (NSDictionary<NSString *, id> *actionItem in processedItems) {
@@ -818,14 +762,6 @@ static NSString *const FB_KEY_ACTIONS = @"actions";
818
762
  }
819
763
 
820
764
  NSArray<NSDictionary<NSString *, id> *> *actionItems = [actionDescription objectForKey:FB_KEY_ACTIONS];
821
- if (nil == actionItems || 0 == actionItems.count) {
822
- NSString *description = [NSString stringWithFormat:@"It is mandatory to have at least one gesture item defined for each action. Action with id '%@' contains none", actionId];
823
- if (error) {
824
- *error = [[FBErrorBuilder.builder withDescription:description] build];
825
- }
826
- return nil;
827
- }
828
-
829
765
  FBW3CGestureItemsChain *chain = [[FBW3CGestureItemsChain alloc] init];
830
766
  NSArray<NSDictionary<NSString *, id> *> *processedItems = [self preprocessedActionItemsWith:actionItems];
831
767
  for (NSDictionary<NSString *, id> *actionItem in processedItems) {
@@ -900,7 +836,20 @@ static NSString *const FB_KEY_ACTIONS = @"actions";
900
836
  *error = [[FBErrorBuilder.builder withDescription:description] build];
901
837
  }
902
838
  return nil;
839
+ }
840
+ NSArray<NSDictionary<NSString *, id> *> *actionItems = [action objectForKey:FB_KEY_ACTIONS];
841
+ if (nil == actionItems) {
842
+ NSString *description = [NSString stringWithFormat:@"It is mandatory to have at least one item defined for each action. Action with id '%@' contains none", actionId];
843
+ if (error) {
844
+ *error = [[FBErrorBuilder.builder withDescription:description] build];
845
+ }
846
+ return nil;
903
847
  }
848
+ if (0 == actionItems.count) {
849
+ [FBLogger logFmt:@"Action items in the action id '%@' had an empty array. Skipping the action.", actionId];
850
+ continue;
851
+ }
852
+
904
853
  [actionIds addObject:actionId];
905
854
  [actionsMapping setObject:action forKey:actionId];
906
855
  }
@@ -140,18 +140,46 @@
140
140
  @{@"type": @"keyUp", @"value": @"N"},
141
141
  @{@"type": @"keyDown", @"value": @"B"},
142
142
  @{@"type": @"keyUp", @"value": @"B"},
143
+ @{@"type": @"keyDown", @"value": @"A"},
144
+ @{@"type": @"keyUp", @"value": @"A"},
143
145
  @{@"type": @"keyDown", @"value": @"a"},
144
146
  @{@"type": @"keyUp", @"value": @"a"},
147
+ @{@"type": @"keyDown", @"value": [NSString stringWithFormat:@"%C", 0xE003]},
148
+ @{@"type": @"keyUp", @"value": [NSString stringWithFormat:@"%C", 0xE003]},
145
149
  @{@"type": @"pause", @"duration": @500},
146
150
  ],
147
151
  },
148
- ];
152
+ ];
153
+ NSError *error;
154
+ XCTAssertTrue([self.testedApplication fb_performW3CActions:typeAction
155
+ elementCache:nil
156
+ error:&error]);
157
+ XCTAssertNil(error);
158
+ XCTAssertEqualObjects(textField.wdValue, @"🏀NBA");
159
+ }
160
+
161
+ - (void)testTextTypingWithEmptyActions
162
+ {
163
+ if (![XCPointerEvent.class fb_areKeyEventsSupported]) {
164
+ return;
165
+ }
166
+
167
+ XCUIElement *textField = self.testedApplication.textFields[@"aIdentifier"];
168
+ [textField tap];
169
+ NSArray<NSDictionary<NSString *, id> *> *typeAction =
170
+ @[
171
+ @{
172
+ @"type": @"pointer",
173
+ @"id": @"touch",
174
+ @"actions": @[],
175
+ },
176
+ ];
149
177
  NSError *error;
150
178
  XCTAssertTrue([self.testedApplication fb_performW3CActions:typeAction
151
179
  elementCache:nil
152
180
  error:&error]);
153
181
  XCTAssertNil(error);
154
- XCTAssertEqualObjects(textField.wdValue, @"🏀NBa");
182
+ XCTAssertEqualObjects(textField.value, @"");
155
183
  }
156
184
 
157
185
  @end
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appium-webdriveragent",
3
- "version": "8.7.6",
3
+ "version": "8.7.8",
4
4
  "description": "Package bundling WebDriverAgent",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",