diff --git a/addon/-private/properties/collection.js b/addon/-private/properties/collection.js
index a07a0447..afdebc52 100644
--- a/addon/-private/properties/collection.js
+++ b/addon/-private/properties/collection.js
@@ -10,6 +10,9 @@ import { collection as legacyCollection } from './collection/legacy';
* Creates a enumerable that represents a collection of items. The collection is zero-indexed
* and has the following public methods and properties:
*
+ * IMPORTANT: You can use Array accessors only on browsers that support Proxy.
+ * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy#Browser_compatibility
+ *
* - `length` - The number of items in the collection.
* - `objectAt()` - Returns the page for the item at the specified index.
* - `filter()` - Filters the items in the array and returns the ones which match the predicate function.
@@ -108,6 +111,26 @@ import { collection as legacyCollection } from './collection/legacy';
* let john = page.users.filter((item) => item.firstName === 'John' )[0];
* assert.equal(john.lastName, 'Doe');
*
+ * @example if the browser you run tests supports Proxy, you can use array accessors to access elements by index
+ *
+ * //
+ * //
+ * // Mary |
+ * // |
+ * //
+ * // John |
+ * // |
+ * //
+ *
+ * const page = PageObject.create({
+ * users: PageObject.collection('tr')
+ * });
+ *
+ * // This only works on browsers that support `Proxy`
+ * assert.equal(page.users[0].text, 'Mary');
+ * assert.equal(page.users[1].text, 'John');
+ *
+ *
* @param {String} scopeOrDefinition - Selector to define the items of the collection
* @param {Object} [definitionOrNothing] - Object with the definition of item properties
* @return {Descriptor}
diff --git a/addon/-private/properties/collection/main.js b/addon/-private/properties/collection/main.js
index dee94082..7cbb0fb5 100644
--- a/addon/-private/properties/collection/main.js
+++ b/addon/-private/properties/collection/main.js
@@ -106,6 +106,22 @@ if (typeof (Symbol) !== 'undefined' && Symbol.iterator) {
}
}
+function proxyIt(instance) {
+ return new window.Proxy(instance, {
+ get: function(target, name) {
+ if (typeof(name) === 'number' || typeof(name) === 'string') {
+ let index = parseInt(name, 10);
+
+ if (!isNaN(index)) {
+ return target.objectAt(index);
+ }
+ }
+
+ return target[name];
+ }
+ });
+}
+
export function collection(scope, definition) {
let descriptor = {
isDescriptor: true,
@@ -115,6 +131,10 @@ export function collection(scope, definition) {
// This does mutate the descriptor, but because `setup` is always called before the
// value is assigned we are guaranteed to get a new, unique Collection instance each time.
descriptor.value = new Collection(scope, definition, node, key);
+
+ if (window.Proxy) {
+ descriptor.value = proxyIt(descriptor.value);
+ }
}
};
diff --git a/tests/unit/-private/properties/collection-test.js b/tests/unit/-private/properties/collection-test.js
index bbf09d04..d70c6e7a 100644
--- a/tests/unit/-private/properties/collection-test.js
+++ b/tests/unit/-private/properties/collection-test.js
@@ -429,4 +429,18 @@ moduleForProperty('collection', function(test) {
assert.deepEqual(page.foo.filterBy('isSpecial').map((i) => i.text), ['Lorem']);
assert.deepEqual(page.foo.filterBy('isFoo').map((i) => i.text), []);
});
+
+ test('uses array accessor', function(assert) {
+ let page = create({
+ foo: collection('span')
+ });
+
+ this.adapter.createTemplate(this, page, `
+ Lorem
+ Ipsum
+ `);
+
+ assert.equal(page.foo[0].text, 'Lorem');
+ assert.equal(page.foo[1].text, 'Ipsum');
+ });
});