XCUIElementFBFindTests.m 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. /**
  2. * Copyright (c) 2015-present, Facebook, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. */
  9. #import <XCTest/XCTest.h>
  10. #import "FBIntegrationTestCase.h"
  11. #import "FBElementUtils.h"
  12. #import "FBExceptions.h"
  13. #import "FBTestMacros.h"
  14. #import "XCUIElement.h"
  15. #import "XCUIElement+FBFind.h"
  16. #import "XCUIElement+FBUID.h"
  17. #import "FBXCElementSnapshotWrapper+Helpers.h"
  18. #import "XCUIElement+FBIsVisible.h"
  19. #import "XCUIElement+FBClassChain.h"
  20. #import "XCUIElement+FBResolve.h"
  21. #import "FBXPath.h"
  22. #import "FBXCodeCompatibility.h"
  23. @interface XCUIElementFBFindTests : FBIntegrationTestCase
  24. @property (nonatomic, strong) XCUIElement *testedView;
  25. @end
  26. @implementation XCUIElementFBFindTests
  27. - (void)setUp
  28. {
  29. [super setUp];
  30. static dispatch_once_t onceToken;
  31. dispatch_once(&onceToken, ^{
  32. [self launchApplication];
  33. });
  34. self.testedView = self.testedApplication.otherElements[@"MainView"];
  35. FBAssertWaitTillBecomesTrue(self.testedView.exists);
  36. }
  37. - (void)testDescendantsWithClassName
  38. {
  39. NSSet<NSString *> *expectedLabels = [NSSet setWithArray:@[
  40. @"Alerts",
  41. @"Attributes",
  42. @"Scrolling",
  43. @"Deadlock app",
  44. @"Touch",
  45. ]];
  46. NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingClassName:@"XCUIElementTypeButton"
  47. shouldReturnAfterFirstMatch:NO];
  48. XCTAssertEqual(matchingSnapshots.count, expectedLabels.count);
  49. NSArray<NSString *> *labels = [matchingSnapshots valueForKeyPath:@"@distinctUnionOfObjects.label"];
  50. XCTAssertEqualObjects([NSSet setWithArray:labels], expectedLabels);
  51. NSArray<NSNumber *> *types = [matchingSnapshots valueForKeyPath:@"@distinctUnionOfObjects.elementType"];
  52. XCTAssertEqual(types.count, 1, @"matchingSnapshots should contain only one type");
  53. XCTAssertEqualObjects(types.lastObject, @(XCUIElementTypeButton), @"matchingSnapshots should contain only one type");
  54. }
  55. - (void)testSingleDescendantWithClassName
  56. {
  57. NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingClassName:@"XCUIElementTypeButton"
  58. shouldReturnAfterFirstMatch:YES];
  59. XCTAssertEqual(matchingSnapshots.count, 1);
  60. XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton);
  61. }
  62. - (void)testDescendantsWithIdentifier
  63. {
  64. NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingIdentifier:@"Alerts"
  65. shouldReturnAfterFirstMatch:NO];
  66. int snapshotsCount = 2;
  67. XCTAssertEqual(matchingSnapshots.count, snapshotsCount);
  68. XCTAssertEqual(matchingSnapshots.firstObject.elementType, XCUIElementTypeButton);
  69. XCTAssertEqualObjects(matchingSnapshots.lastObject.label, @"Alerts");
  70. NSArray<XCUIElement *> *selfElementsById = [matchingSnapshots.lastObject fb_descendantsMatchingIdentifier:@"Alerts" shouldReturnAfterFirstMatch:NO];
  71. XCTAssertEqual(selfElementsById.count, 1);
  72. }
  73. - (void)testSingleDescendantWithIdentifier
  74. {
  75. NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingIdentifier:@"Alerts"
  76. shouldReturnAfterFirstMatch:YES];
  77. XCTAssertEqual(matchingSnapshots.count, 1);
  78. XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton);
  79. XCTAssertEqualObjects(matchingSnapshots.lastObject.label, @"Alerts");
  80. }
  81. - (void)testStableInstance
  82. {
  83. NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingIdentifier:@"Alerts"
  84. shouldReturnAfterFirstMatch:YES];
  85. XCTAssertEqual(matchingSnapshots.count, 1);
  86. for (XCUIElement *el in @[
  87. matchingSnapshots.lastObject,
  88. [matchingSnapshots.lastObject fb_stableInstanceWithUid:[matchingSnapshots.lastObject fb_uid]]
  89. ]) {
  90. XCTAssertEqual(el.elementType, XCUIElementTypeButton);
  91. XCTAssertEqualObjects(el.label, @"Alerts");
  92. }
  93. }
  94. - (void)testSingleDescendantWithMissingIdentifier
  95. {
  96. NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingIdentifier:@"blabla" shouldReturnAfterFirstMatch:YES];
  97. XCTAssertEqual(matchingSnapshots.count, 0);
  98. }
  99. - (void)testDescendantsWithXPathQuery
  100. {
  101. NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButton[@label='Alerts']"
  102. shouldReturnAfterFirstMatch:NO];
  103. XCTAssertEqual(matchingSnapshots.count, 1);
  104. XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton);
  105. XCTAssertEqualObjects(matchingSnapshots.lastObject.label, @"Alerts");
  106. }
  107. - (void)testSelfWithXPathQuery
  108. {
  109. NSArray<XCUIElement *> *matchingSnapshots = [self.testedApplication fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeApplication"
  110. shouldReturnAfterFirstMatch:NO];
  111. XCTAssertEqual(matchingSnapshots.count, 1);
  112. XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeApplication);
  113. }
  114. - (void)testSingleDescendantWithXPathQuery
  115. {
  116. NSArray<XCUIElement *> *matchingSnapshots = [self.testedApplication fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButton[@hittable='true']"
  117. shouldReturnAfterFirstMatch:YES];
  118. XCTAssertEqual(matchingSnapshots.count, 1);
  119. XCUIElement *matchingSnapshot = [matchingSnapshots firstObject];
  120. XCTAssertNotNil(matchingSnapshot);
  121. XCTAssertEqual(matchingSnapshot.elementType, XCUIElementTypeButton);
  122. XCTAssertEqualObjects(matchingSnapshot.label, @"Alerts");
  123. }
  124. - (void)testSingleDescendantWithXPathQueryNoMatches
  125. {
  126. XCUIElement *matchingSnapshot = [[self.testedView fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButtonnn"
  127. shouldReturnAfterFirstMatch:YES] firstObject];
  128. XCTAssertNil(matchingSnapshot);
  129. }
  130. - (void)testSingleLastDescendantWithXPathQuery
  131. {
  132. XCUIElement *matchingSnapshot = [[self.testedView fb_descendantsMatchingXPathQuery:@"(//XCUIElementTypeButton)[last()]"
  133. shouldReturnAfterFirstMatch:YES] firstObject];
  134. XCTAssertNotNil(matchingSnapshot);
  135. XCTAssertEqual(matchingSnapshot.elementType, XCUIElementTypeButton);
  136. }
  137. - (void)testDescendantsWithXPathQueryNoMatches
  138. {
  139. NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButton[@label='Alerts1']"
  140. shouldReturnAfterFirstMatch:NO];
  141. XCTAssertEqual(matchingSnapshots.count, 0);
  142. }
  143. - (void)testDescendantsWithComplexXPathQuery
  144. {
  145. NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingXPathQuery:@"//*[@label='Scrolling']/preceding::*[boolean(string(@label))]"
  146. shouldReturnAfterFirstMatch:NO];
  147. int snapshotsCount = 6;
  148. XCTAssertEqual(matchingSnapshots.count, snapshotsCount);
  149. }
  150. - (void)testDescendantsWithWrongXPathQuery
  151. {
  152. XCTAssertThrowsSpecificNamed([self.testedView fb_descendantsMatchingXPathQuery:@"//*[blabla(@label, Scrolling')]"
  153. shouldReturnAfterFirstMatch:NO],
  154. NSException, FBInvalidXPathException);
  155. }
  156. - (void)testFirstDescendantWithWrongXPathQuery
  157. {
  158. XCTAssertThrowsSpecificNamed([self.testedView fb_descendantsMatchingXPathQuery:@"//*[blabla(@label, Scrolling')]"
  159. shouldReturnAfterFirstMatch:YES],
  160. NSException, FBInvalidXPathException);
  161. }
  162. - (void)testVisibleDescendantWithXPathQuery
  163. {
  164. NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButton[@name='Alerts' and @enabled='true' and @visible='true']" shouldReturnAfterFirstMatch:NO];
  165. XCTAssertEqual(matchingSnapshots.count, 1);
  166. XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton);
  167. XCTAssertTrue(matchingSnapshots.lastObject.isEnabled);
  168. XCTAssertTrue(matchingSnapshots.lastObject.fb_isVisible);
  169. XCTAssertEqualObjects(matchingSnapshots.lastObject.label, @"Alerts");
  170. }
  171. - (void)testDescendantsWithPredicateString
  172. {
  173. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"label = 'Alerts'"];
  174. NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingPredicate:predicate
  175. shouldReturnAfterFirstMatch:NO];
  176. int snapshotsCount = 2;
  177. XCTAssertEqual(matchingSnapshots.count, snapshotsCount);
  178. XCTAssertEqual(matchingSnapshots.firstObject.elementType, XCUIElementTypeButton);
  179. XCTAssertEqualObjects(matchingSnapshots.lastObject.label, @"Alerts");
  180. NSPredicate *selfPredicate = [NSPredicate predicateWithFormat:@"label == 'Alerts'"];
  181. NSArray<XCUIElement *> *selfElementsByPredicate = [matchingSnapshots.lastObject fb_descendantsMatchingPredicate:selfPredicate
  182. shouldReturnAfterFirstMatch:NO];
  183. XCTAssertEqual(selfElementsByPredicate.count, 1);
  184. }
  185. - (void)testSelfWithPredicateString
  186. {
  187. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"type == 'XCUIElementTypeApplication'"];
  188. NSArray<XCUIElement *> *matchingSnapshots = [self.testedApplication fb_descendantsMatchingPredicate:predicate
  189. shouldReturnAfterFirstMatch:NO];
  190. XCTAssertEqual(matchingSnapshots.count, 1);
  191. XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeApplication);
  192. }
  193. - (void)testSingleDescendantWithPredicateString
  194. {
  195. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"type = 'XCUIElementTypeButton'"];
  196. NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingPredicate:predicate shouldReturnAfterFirstMatch:YES];
  197. XCTAssertEqual(matchingSnapshots.count, 1);
  198. XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton);
  199. }
  200. - (void)testSingleDescendantWithPredicateStringByIndex
  201. {
  202. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"type == 'XCUIElementTypeButton' AND index == 2"];
  203. NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingPredicate:predicate shouldReturnAfterFirstMatch:NO];
  204. XCTAssertEqual(matchingSnapshots.count, 1);
  205. XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton);
  206. }
  207. - (void)testDescendantsWithPropertyStrict
  208. {
  209. NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingProperty:@"label"
  210. value:@"Alert"
  211. partialSearch:NO];
  212. XCTAssertEqual(matchingSnapshots.count, 0);
  213. matchingSnapshots = [self.testedView fb_descendantsMatchingProperty:@"label" value:@"Alerts" partialSearch:NO];
  214. int snapshotsCount = 2;
  215. XCTAssertEqual(matchingSnapshots.count, snapshotsCount);
  216. XCTAssertEqual(matchingSnapshots.firstObject.elementType, XCUIElementTypeButton);
  217. XCTAssertEqualObjects(matchingSnapshots.lastObject.label, @"Alerts");
  218. }
  219. - (void)testGlobalWithPropertyStrict
  220. {
  221. NSArray<XCUIElement *> *matchingSnapshots = [self.testedApplication fb_descendantsMatchingProperty:@"label"
  222. value:@"Alert"
  223. partialSearch:NO];
  224. XCTAssertEqual(matchingSnapshots.count, 0);
  225. matchingSnapshots = [self.testedApplication fb_descendantsMatchingProperty:@"label" value:@"Alerts" partialSearch:NO];
  226. int snapshotsCount = 2;
  227. XCTAssertEqual(matchingSnapshots.count, snapshotsCount);
  228. XCTAssertEqual(matchingSnapshots.firstObject.elementType, XCUIElementTypeButton);
  229. XCTAssertEqualObjects(matchingSnapshots.lastObject.label, @"Alerts");
  230. }
  231. - (void)testDescendantsWithPropertyPartial
  232. {
  233. NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingProperty:@"label"
  234. value:@"Alerts"
  235. partialSearch:NO];
  236. int snapshotsCount = 2;
  237. XCTAssertEqual(matchingSnapshots.count, snapshotsCount);
  238. XCTAssertEqual(matchingSnapshots.firstObject.elementType, XCUIElementTypeButton);
  239. XCTAssertEqualObjects(matchingSnapshots.lastObject.label, @"Alerts");
  240. }
  241. - (void)testDescendantsWithClassChain
  242. {
  243. NSArray<XCUIElement *> *matchingSnapshots;
  244. NSString *queryString =@"XCUIElementTypeWindow/XCUIElementTypeOther/**/XCUIElementTypeButton";
  245. matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString
  246. shouldReturnAfterFirstMatch:NO];
  247. XCTAssertEqual(matchingSnapshots.count, 5); // /XCUIElementTypeButton
  248. for (XCUIElement *matchingSnapshot in matchingSnapshots) {
  249. XCTAssertEqual(matchingSnapshot.elementType, XCUIElementTypeButton);
  250. }
  251. }
  252. - (void)testDescendantsWithClassChainWithIndex
  253. {
  254. NSArray<XCUIElement *> *matchingSnapshots;
  255. // iPhone
  256. NSString *queryString = @"XCUIElementTypeWindow/*/*/*/*[2]/*/*/XCUIElementTypeButton";
  257. matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString
  258. shouldReturnAfterFirstMatch:NO];
  259. if (matchingSnapshots.count == 0) {
  260. // iPad
  261. queryString = @"XCUIElementTypeWindow/*/*/*/*/*[2]/*/*/XCUIElementTypeButton";
  262. matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString
  263. shouldReturnAfterFirstMatch:NO];
  264. }
  265. XCTAssertEqual(matchingSnapshots.count, 5); // /XCUIElementTypeButton
  266. for (XCUIElement *matchingSnapshot in matchingSnapshots) {
  267. XCTAssertEqual(matchingSnapshot.elementType, XCUIElementTypeButton);
  268. }
  269. }
  270. - (void)testDescendantsWithClassChainAndPredicates
  271. {
  272. NSArray<XCUIElement *> *matchingSnapshots;
  273. NSString *queryString = @"XCUIElementTypeWindow/**/XCUIElementTypeButton[`label BEGINSWITH 'A'`]";
  274. matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString
  275. shouldReturnAfterFirstMatch:NO];
  276. XCTAssertEqual(matchingSnapshots.count, 2);
  277. XCTAssertEqualObjects([matchingSnapshots firstObject].label, @"Alerts");
  278. XCTAssertEqualObjects([matchingSnapshots lastObject].label, @"Attributes");
  279. }
  280. - (void)testDescendantsWithIndirectClassChainAndPredicates
  281. {
  282. NSString *queryString = @"XCUIElementTypeWindow/**/XCUIElementTypeButton[`label BEGINSWITH 'A'`]";
  283. NSArray<XCUIElement *> *simpleQueryMatches = [self.testedApplication fb_descendantsMatchingClassChain:queryString
  284. shouldReturnAfterFirstMatch:NO];
  285. NSArray<XCUIElement *> *deepQueryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"XCUIElementTypeWindow/**/XCUIElementTypeButton[`label BEGINSWITH 'A'`]"
  286. shouldReturnAfterFirstMatch:NO];
  287. XCTAssertEqual(simpleQueryMatches.count, deepQueryMatches.count);
  288. XCTAssertEqualObjects([simpleQueryMatches firstObject].label, [deepQueryMatches firstObject].label);
  289. XCTAssertEqualObjects([simpleQueryMatches lastObject].label, [deepQueryMatches lastObject].label);
  290. }
  291. - (void)testClassChainWithDescendantPredicate
  292. {
  293. NSArray<XCUIElement *> *simpleQueryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"XCUIElementTypeWindow/*/*[1]"
  294. shouldReturnAfterFirstMatch:NO];
  295. NSArray<XCUIElement *> *predicateQueryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"XCUIElementTypeWindow/*/*[$type == 'XCUIElementTypeButton' AND label BEGINSWITH 'A'$]"
  296. shouldReturnAfterFirstMatch:NO];
  297. XCTAssertEqual(simpleQueryMatches.count, predicateQueryMatches.count);
  298. XCTAssertEqual([simpleQueryMatches firstObject].elementType, [predicateQueryMatches firstObject].elementType);
  299. XCTAssertEqual([simpleQueryMatches lastObject].elementType, [predicateQueryMatches lastObject].elementType);
  300. }
  301. - (void)testSingleDescendantWithComplexIndirectClassChain
  302. {
  303. NSArray<XCUIElement *> *queryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"**/*/XCUIElementTypeButton[2]"
  304. shouldReturnAfterFirstMatch:NO];
  305. XCTAssertEqual(queryMatches.count, 1);
  306. XCTAssertEqual(queryMatches.lastObject.elementType, XCUIElementTypeButton);
  307. XCTAssertEqualObjects(queryMatches.lastObject.label, @"Deadlock app");
  308. }
  309. - (void)testSingleDescendantWithComplexIndirectClassChainAndZeroMatches
  310. {
  311. NSArray<XCUIElement *> *queryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"**/*/XCUIElementTypeWindow"
  312. shouldReturnAfterFirstMatch:NO];
  313. XCTAssertEqual(queryMatches.count, 0);
  314. }
  315. - (void)testDescendantsWithClassChainAndPredicatesAndIndexes
  316. {
  317. NSArray<XCUIElement *> *matchingSnapshots;
  318. NSString *queryString = @"XCUIElementTypeWindow[`name != 'bla'`]/**/XCUIElementTypeButton[`label BEGINSWITH \"A\"`][1]";
  319. matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString
  320. shouldReturnAfterFirstMatch:NO];
  321. XCTAssertEqual(matchingSnapshots.count, 1);
  322. XCTAssertEqualObjects([matchingSnapshots firstObject].label, @"Alerts");
  323. }
  324. - (void)testSingleDescendantWithClassChain
  325. {
  326. NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingClassChain:@"XCUIElementTypeButton"
  327. shouldReturnAfterFirstMatch:YES];
  328. XCTAssertEqual(matchingSnapshots.count, 1);
  329. XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton);
  330. XCTAssertTrue([matchingSnapshots.lastObject.label isEqualToString:@"Alerts"]);
  331. }
  332. - (void)testSingleDescendantWithClassChainAndNegativeIndex
  333. {
  334. NSArray<XCUIElement *> *matchingSnapshots;
  335. matchingSnapshots = [self.testedView fb_descendantsMatchingClassChain:@"XCUIElementTypeButton[-1]"
  336. shouldReturnAfterFirstMatch:YES];
  337. XCTAssertEqual(matchingSnapshots.count, 1);
  338. XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton);
  339. XCTAssertTrue([matchingSnapshots.lastObject.label isEqualToString:@"Touch"]);
  340. matchingSnapshots = [self.testedView fb_descendantsMatchingClassChain:@"XCUIElementTypeButton[-10]"
  341. shouldReturnAfterFirstMatch:YES];
  342. XCTAssertEqual(matchingSnapshots.count, 0);
  343. }
  344. - (void)testInvalidQueryWithClassChain
  345. {
  346. XCTAssertThrowsSpecificNamed([self.testedView fb_descendantsMatchingClassChain:@"NoXCUIElementTypePrefix"
  347. shouldReturnAfterFirstMatch:YES],
  348. NSException, FBClassChainQueryParseException);
  349. }
  350. - (void)testHandleInvalidQueryWithClassChainAsNoElementWithoutError
  351. {
  352. NSArray<XCUIElement *> *matchingSnapshots = [self.testedView
  353. fb_descendantsMatchingClassChain:@"XCUIElementTypeBlabla"
  354. shouldReturnAfterFirstMatch:YES];
  355. XCTAssertEqual(matchingSnapshots.count, 0);
  356. }
  357. - (void)testClassChainWithInvalidPredicate
  358. {
  359. XCTAssertThrowsSpecificNamed([self.testedApplication fb_descendantsMatchingClassChain:@"XCUIElementTypeWindow[`bla != 'bla'`]"
  360. shouldReturnAfterFirstMatch:NO],
  361. NSException, FBUnknownAttributeException);;
  362. }
  363. @end
  364. @interface XCUIElementFBFindTests_AttributesPage : FBIntegrationTestCase
  365. @end
  366. @implementation XCUIElementFBFindTests_AttributesPage
  367. - (void)setUp
  368. {
  369. [super setUp];
  370. static dispatch_once_t onceToken;
  371. dispatch_once(&onceToken, ^{
  372. [self launchApplication];
  373. [self goToAttributesPage];
  374. });
  375. }
  376. - (void)testNestedQueryWithClassChain
  377. {
  378. NSString *queryString = @"XCUIElementTypePicker";
  379. FBAssertWaitTillBecomesTrue(self.testedApplication.buttons[@"Button"].fb_isVisible);
  380. XCUIElement *datePicker = [self.testedApplication
  381. descendantsMatchingType:XCUIElementTypeDatePicker].allElementsBoundByIndex.firstObject;
  382. NSArray<XCUIElement *> *matches = [datePicker fb_descendantsMatchingClassChain:queryString
  383. shouldReturnAfterFirstMatch:NO];
  384. XCTAssertEqual(matches.count, 1);
  385. XCUIElementType expectedType = XCUIElementTypePicker;
  386. XCTAssertEqual([matches firstObject].elementType, expectedType);
  387. }
  388. @end
  389. @interface XCUIElementFBFindTests_ScrollPage : FBIntegrationTestCase
  390. @end
  391. @implementation XCUIElementFBFindTests_ScrollPage
  392. - (void)setUp
  393. {
  394. [super setUp];
  395. static dispatch_once_t onceToken;
  396. dispatch_once(&onceToken, ^{
  397. [self launchApplication];
  398. [self goToScrollPageWithCells:YES];
  399. });
  400. }
  401. - (void)testInvisibleDescendantWithXPathQuery
  402. {
  403. NSArray<XCUIElement *> *matchingSnapshots = [self.testedApplication fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeStaticText[@visible='false']"
  404. shouldReturnAfterFirstMatch:NO];
  405. XCTAssertGreaterThan(matchingSnapshots.count, 1);
  406. XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeStaticText);
  407. XCTAssertFalse(matchingSnapshots.lastObject.fb_isVisible);
  408. }
  409. - (void)testNonHittableDescendantWithXPathQuery
  410. {
  411. NSArray<XCUIElement *> *matchingSnapshots = [self.testedApplication fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeStaticText[@hittable='false']"
  412. shouldReturnAfterFirstMatch:NO];
  413. XCTAssertGreaterThan(matchingSnapshots.count, 1);
  414. XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeStaticText);
  415. XCTAssertFalse(matchingSnapshots.lastObject.fb_isVisible);
  416. }
  417. @end