Skip to content

Commit

Permalink
Move to real find methods, not findByElOrEls
Browse files Browse the repository at this point in the history
  • Loading branch information
imurchie committed Feb 7, 2018
1 parent 76f7591 commit 9bee5c1
Show file tree
Hide file tree
Showing 19 changed files with 91 additions and 95 deletions.
3 changes: 0 additions & 3 deletions lib/commands/find.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ helpers.doFindElementOrEls = async function (params) {
// mult: multiple elements or just one?
// context: finding an element from the root context? or starting from another element
helpers.findElOrEls = async function (strategy, selector, mult, context = '') {
// throws error if not valid, uses this.locatorStrategies
this.validateLocatorStrategy(strategy);

if (!selector) {
throw new Error("Must provide a selector when finding elements");
}
Expand Down
2 changes: 1 addition & 1 deletion test/functional/commands/actions-e2e-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ describe('actions', function () {

describe('replaceValue', function () {
it('should replace existing value in a text field', async function () {
let el = _.last(await driver.findElOrEls('class name', 'android.widget.EditText', true));
let el = _.last(await driver.findElements('class name', 'android.widget.EditText'));
el.should.exist;
await driver.setValue('original value', el.ELEMENT);
await driver.getText(el.ELEMENT).should.eventually.equal('original value');
Expand Down
4 changes: 2 additions & 2 deletions test/functional/commands/basic/attribute-e2e-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('apidemo - attributes', function () {
before(async function () {
driver = new AndroidDriver();
await driver.createSession(DEFAULT_CAPS);
let animation = await driver.findElOrEls('accessibility id', 'Animation', false);
let animation = await driver.findElement('accessibility id', 'Animation');
animationEl = animation.ELEMENT;
});
after(async function () {
Expand All @@ -31,7 +31,7 @@ describe('apidemo - attributes', function () {
});
it('should be able to find name attribute, falling back to text', async function () {
await driver.click(animationEl);
let textView = await driver.findElOrEls('class name', 'android.widget.TextView', true);
let textView = await driver.findElements('class name', 'android.widget.TextView');
let textViewEl = textView[1].ELEMENT;
await driver.getAttribute('name', textViewEl).should.eventually.become('Bouncing Balls');
await driver.back();
Expand Down
2 changes: 1 addition & 1 deletion test/functional/commands/basic/element-e2e-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('element', function () {
before(async function () {
driver = new AndroidDriver();
await driver.createSession(caps);
el = _.last(await driver.findElOrEls('class name', 'android.widget.EditText', true));
el = _.last(await driver.findElements('class name', 'android.widget.EditText'));
el.should.exist;
});
after(async function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ describe('Find - accessibility ID', function () {
await driver.deleteSession();
});
it('should find an element by name', async function () {
await driver.findElOrEls('accessibility id', 'Animation', false).should.eventually.exist;
await driver.findElement('accessibility id', 'Animation').should.eventually.exist;
});
it('should return an array of one element if the `multi` param is true', async function () {
let els = await driver.findElOrEls('accessibility id', 'Animation', true);
let els = await driver.findElements('accessibility id', 'Animation');
els.should.be.an.instanceof(Array);
els.should.have.length(1);
});
it('should find an element with a content-desc property containing an apostrophe', async function () {
await driver.findElOrEls('accessibility id', "Access'ibility", false).should.eventually.exist;
await driver.findElement('accessibility id', `Access'ibility`).should.eventually.exist;
});
});
4 changes: 2 additions & 2 deletions test/functional/commands/find/by-id-e2e-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ describe('Find - ID', function () {
await driver.deleteSession();
});
it('should find an element by id', async function () {
await driver.findElOrEls('id', 'android:id/text1', false).should.eventually.exist;
await driver.findElement('id', 'android:id/text1').should.eventually.exist;
});
it('should return an array of one element if the `multi` param is true', async function () {
// TODO: this returns an object instead of an array. Investigate.
let els = await driver.findElOrEls('id', 'android:id/text1', true);
let els = await driver.findElements('id', 'android:id/text1');
els.should.be.an.instanceof(Array);
els.should.have.length.above(1);
});
Expand Down
54 changes: 27 additions & 27 deletions test/functional/commands/find/by-uiautomator-e2e-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,119 +17,119 @@ describe('Find - uiautomator', function () {
await driver.deleteSession();
});
it('should find elements with a boolean argument', async function () {
await driver.findElOrEls('-android uiautomator', 'new UiSelector().clickable(true)', true)
await driver.findElements('-android uiautomator', 'new UiSelector().clickable(true)')
.should.eventually.have.length.at.least(10);
});
it('should find elements within the context of another element', async function () {
let els = await driver
.findElOrEls('-android uiautomator', 'new UiSelector().className("android.widget.TextView")', true);
.findElements('-android uiautomator', 'new UiSelector().className("android.widget.TextView")');
els.length.should.be.above(8);
els.length.should.be.below(14);
});
it('should find elements without prepending "new UiSelector()"', async function () {
await driver.findElOrEls('-android uiautomator', '.clickable(true)', true)
await driver.findElements('-android uiautomator', '.clickable(true)')
.should.eventually.have.length.at.least(10);
});
it('should find elements without prepending "new UiSelector()"', async function () {
await driver.findElOrEls('-android uiautomator', '.clickable(true)', true)
await driver.findElements('-android uiautomator', '.clickable(true)')
.should.eventually.have.length.at.least(10);
});
it('should find elements without prepending "new UiSelector()"', async function () {
await driver.findElOrEls('-android uiautomator', 'clickable(true)', true)
await driver.findElements('-android uiautomator', 'clickable(true)')
.should.eventually.have.length.at.least(10);
});
it('should find elements without prepending "new "', async function () {
await driver.findElOrEls('-android uiautomator', 'UiSelector().clickable(true)', true)
await driver.findElements('-android uiautomator', 'UiSelector().clickable(true)')
.should.eventually.have.length.at.least(10);
});
it('should ignore trailing semicolons', async function () {
await driver.findElOrEls('-android uiautomator', 'new UiSelector().clickable(true);', true)
await driver.findElements('-android uiautomator', 'new UiSelector().clickable(true);')
.should.eventually.have.length.at.least(10);
});
it('should find an element with an int argument', async function () {
let el = await driver.findElOrEls('-android uiautomator', 'new UiSelector().index(0)', false);
let el = await driver.findElement('-android uiautomator', 'new UiSelector().index(0)');
await driver.getName(el.ELEMENT).should.eventually.equal('android.widget.FrameLayout');
});
it('should find an element with a string argument', async function () {
await driver
.findElOrEls('-android uiautomator', 'new UiSelector().description("Animation")', false)
.findElement('-android uiautomator', 'new UiSelector().description("Animation")')
.should.eventually.exist;
});
it('should find an element with an overloaded method argument', async function () {
await driver.findElOrEls('-android uiautomator', 'new UiSelector().className("android.widget.TextView")', true)
await driver.findElements('-android uiautomator', 'new UiSelector().className("android.widget.TextView")')
.should.eventually.have.length.at.least(10);
});
it('should find an element with a Class<T> method argument', async function () {
await driver.findElOrEls('-android uiautomator', 'new UiSelector().className(android.widget.TextView)', true)
await driver.findElements('-android uiautomator', 'new UiSelector().className(android.widget.TextView)')
.should.eventually.have.length.at.least(10);
});
it('should find an element with a long chain of methods', async function () {
let el = await driver.findElOrEls('-android uiautomator', 'new UiSelector().clickable(true).className(android.widget.TextView).index(1)', false);
let el = await driver.findElement('-android uiautomator', 'new UiSelector().clickable(true).className(android.widget.TextView).index(1)');
await driver.getText(el.ELEMENT).should.eventually.equal('Accessibility');
});
it('should find an element with recursive UiSelectors', async function () {
// TODO: figure out why this fails with 7.1.1
if (await driver.adb.getApiLevel() >= 24) return this.skip(); //eslint-disable-line curly

await driver.findElOrEls('-android uiautomator', 'new UiSelector().childSelector(new UiSelector().clickable(true)).clickable(true)', true)
await driver.findElements('-android uiautomator', 'new UiSelector().childSelector(new UiSelector().clickable(true)).clickable(true)')
.should.eventually.have.length(1);
});
it('should not find an element with bad syntax', async function () {
await driver.findElOrEls('-android uiautomator', 'new UiSelector().clickable((true)', true)
await driver.findElements('-android uiautomator', 'new UiSelector().clickable((true)')
.should.eventually.be.rejectedWith(/resource could not be found/);
});
it('should not find an element with bad syntax', async function () {
await driver.findElOrEls('-android uiautomator', 'new UiSelector().drinkable(true)', true)
await driver.findElements('-android uiautomator', 'new UiSelector().drinkable(true)')
.should.eventually.be.rejectedWith(/resource could not be found/);
});
it('should not find an element which does not exist', async function () {
await driver.findElOrEls('-android uiautomator', 'new UiSelector().description("chuckwudi")', true)
await driver.findElements('-android uiautomator', 'new UiSelector().description("chuckwudi")')
.should.eventually.have.length(0);
});
it('should allow multiple selector statements and return the Union of the two sets', async function () {
let clickable = await driver.findElOrEls('-android uiautomator', 'new UiSelector().clickable(true)', true);
let clickable = await driver.findElements('-android uiautomator', 'new UiSelector().clickable(true)');
clickable.length.should.be.above(0);
let notClickable = await driver.findElOrEls('-android uiautomator', 'new UiSelector().clickable(false)', true);
let notClickable = await driver.findElements('-android uiautomator', 'new UiSelector().clickable(false)');
notClickable.length.should.be.above(0);
let both = await driver.findElOrEls('-android uiautomator', 'new UiSelector().clickable(true); new UiSelector().clickable(false);', true);
let both = await driver.findElements('-android uiautomator', 'new UiSelector().clickable(true); new UiSelector().clickable(false);');
both.should.have.length(clickable.length + notClickable.length);
});
it('should allow multiple selector statements and return the Union of the two sets', async function () {
let clickable = await driver.findElOrEls('-android uiautomator', 'new UiSelector().clickable(true)', true);
let clickable = await driver.findElements('-android uiautomator', 'new UiSelector().clickable(true)');
clickable.length.should.be.above(0);
let clickableClickable = await driver.findElOrEls('-android uiautomator', 'new UiSelector().clickable(true); new UiSelector().clickable(true);', true);
let clickableClickable = await driver.findElements('-android uiautomator', 'new UiSelector().clickable(true); new UiSelector().clickable(true);');
clickableClickable.length.should.be.above(0);
clickableClickable.should.have.length(clickable.length);
});
it('should find an element in the second selector if the first finds no elements', async function () {
let selector = 'new UiSelector().className("not.a.class"); new UiSelector().className("android.widget.TextView")';
await driver.findElOrEls('-android uiautomator', selector, true)
await driver.findElements('-android uiautomator', selector)
.should.eventually.exist;
});
it('should scroll to, and return elements using UiScrollable', async function () {
let selector = 'new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().text("Views").instance(0))';
let el = await driver.findElOrEls('-android uiautomator', selector, false);
let el = await driver.findElement('-android uiautomator', selector);
await driver.getText(el.ELEMENT).should.eventually.equal('Views');
});
it('should allow chaining UiScrollable methods', async function () {
let selector = 'new UiScrollable(new UiSelector().scrollable(true).instance(0)).setMaxSearchSwipes(10).scrollIntoView(new UiSelector().text("Views").instance(0))';
let el = await driver.findElOrEls('-android uiautomator', selector, false);
let el = await driver.findElement('-android uiautomator', selector);
await driver.getText(el.ELEMENT).should.eventually.equal('Views');
});
it('should allow UiScrollable scrollIntoView', async function () {
let selector = 'new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().text("Views").instance(0));';
let el = await driver.findElOrEls('-android uiautomator', selector, false);
let el = await driver.findElement('-android uiautomator', selector);
await driver.getText(el.ELEMENT).should.eventually.equal('Views');
});
it('should error reasonably if a UiScrollable does not return a UiObject', async function () {
let selector = 'new UiScrollable(new UiSelector().scrollable(true).instance(0)).setMaxSearchSwipes(10)';
await driver.findElOrEls('-android uiautomator', selector, false)
await driver.findElement('-android uiautomator', selector)
.should.eventually.be.rejectedWith(/resource could not be found/);
});
it('should allow UiScrollable with unicode string', async function () {
await driver.startActivity('io.appium.android.apis', '.text.Unicode');
let selector = 'new UiSelector().text("عربي").instance(0);';
let el = await driver.findElOrEls('-android uiautomator', selector, false);
let el = await driver.findElement('-android uiautomator', selector);
await driver.getText(el.ELEMENT).should.eventually.equal('عربي');
});
});
26 changes: 13 additions & 13 deletions test/functional/commands/find/by-xpath-e2e-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,58 +20,58 @@ describe('Find - xpath', function () {
await driver.deleteSession();
});
it('should throw when matching nothing', async function () {
await driver.findElOrEls('xpath', '//whatthat', false).should.eventually.be.rejectedWith(/could not be located/);
await driver.findElement('xpath', '//whatthat').should.eventually.be.rejectedWith(/could not be located/);
});
it('should throw with status 7 for hierarchy root', async function () {
await driver.findElOrEls('xpath', '/*', false).should.eventually.be.rejectedWith(/could not be located/);
await driver.findElement('xpath', '/*').should.eventually.be.rejectedWith(/could not be located/);
});
it('should find element by type', async function () {
let el = await driver.findElOrEls('xpath', `//${atv}`, false);
let el = await driver.findElement('xpath', `//${atv}`);
await driver.getText(el.ELEMENT).should.eventually.equal('API Demos');
});
it('should find element by text', async function () {
let el = await driver.findElOrEls('xpath', `//${atv}[@text='Accessibility']`, false);
let el = await driver.findElement('xpath', `//${atv}[@text='Accessibility']`);
await driver.getText(el.ELEMENT).should.eventually.equal('Accessibility');
});
it('should find exactly one element via elementsByXPath', async function () {
let el = await driver.findElOrEls('xpath', `//${atv}[@text='Accessibility']`, true);
let el = await driver.findElements('xpath', `//${atv}[@text='Accessibility']`);
el.length.should.equal(1);
await driver.getText(el[0].ELEMENT).should.eventually.equal('Accessibility');
});
it('should find element by partial text', async function () {
let el = await driver.findElOrEls('xpath', `//${atv}[contains(@text, 'Accessibility')]`, false);
let el = await driver.findElement('xpath', `//${atv}[contains(@text, 'Accessibility')]`);
await driver.getText(el.ELEMENT).should.eventually.equal('Accessibility');
});
it('should find the last element', async function () {
let el = await driver.findElOrEls('xpath', `(//${atv})[last()]`, false);
let el = await driver.findElement('xpath', `(//${atv})[last()]`);
let text = await driver.getText(el.ELEMENT);
["OS", "Text", "Views", "Preference"].should.include(text);
});

// TODO: Doesn't work on CI. Works locally on API_LEVEL 23
//it('should find element by xpath index and child @skip-ci', async () => {
// let alv = 'android.widget.ListView';
// let el = await driver.findElOrEls('xpath', `//${f}[2]/${alv}[1]/${atv}[4]`, false);
// let el = await driver.findElement('xpath', `//${f}[2]/${alv}[1]/${atv}[4]`);
// await driver.getText(el.ELEMENT).should.eventually.equal('App');
//});

it('should find element by index and embedded desc', async function () {
let el = await driver.findElOrEls('xpath', `//${f}//${atv}[5]`, false);
let el = await driver.findElement('xpath', `//${f}//${atv}[5]`);
await driver.getText(el.ELEMENT).should.eventually.equal('Content');
});
it('should find all elements', async function () {
let el = await driver.findElOrEls('xpath', `//*`, true);
let el = await driver.findElement('xpath', `//*`);
el.length.should.be.above(2);
});
it('should find the first element when searching for all elements', async function () {
let el = await driver.findElOrEls('xpath', `//*`, true);
let el = await driver.findElements('xpath', `//*`);
el[0].should.exist;
});
it('should find less elements with compression turned on', async function () {
await driver.updateSettings({ignoreUnimportantViews: false});
let elementsWithoutCompression = await driver.findElOrEls('xpath', `//*`, true);
let elementsWithoutCompression = await driver.findElements('xpath', `//*`);
await driver.updateSettings({ignoreUnimportantViews: true});
let elementsWithCompression = await driver.findElOrEls('xpath', `//*`, true);
let elementsWithCompression = await driver.findElements('xpath', `//*`);
elementsWithoutCompression.length.should.be.greaterThan(elementsWithCompression.length);
});
});
Loading

0 comments on commit 9bee5c1

Please sign in to comment.