Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
477
gaia/apps/communications/contacts/test/marionette/lib/contacts.js
Executable file
477
gaia/apps/communications/contacts/test/marionette/lib/contacts.js
Executable file
|
|
@ -0,0 +1,477 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* Abstraction around contacts app.
|
||||
* @constructor
|
||||
* @param {Marionette.Client} client for operations.
|
||||
*/
|
||||
function Contacts(client) {
|
||||
this.client = client;
|
||||
this.client.setSearchTimeout(10000);
|
||||
this.actions = this.client.loader.getActions();
|
||||
}
|
||||
|
||||
/**
|
||||
* @type String Origin of contacts app
|
||||
*/
|
||||
Contacts.URL = 'app://communications.gaiamobile.org';
|
||||
|
||||
Contacts.config = {
|
||||
prefs: {
|
||||
'device.storage.enabled': true,
|
||||
'device.storage.testing': true,
|
||||
'device.storage.prompt.testing': true
|
||||
}
|
||||
};
|
||||
|
||||
Contacts.Selectors = {
|
||||
body: 'body',
|
||||
bodyReady: 'body .view-body',
|
||||
|
||||
settingsButton: '#settings-button',
|
||||
|
||||
confirmHeader: '#confirmation-message h1',
|
||||
confirmBody: '#confirmation-message p',
|
||||
confirmDismiss: '#confirmation-message menu button',
|
||||
confirmDelete: '#confirmation-message .danger',
|
||||
|
||||
details: '#view-contact-details',
|
||||
detailsEditContact: '#edit-contact-button',
|
||||
detailsTelLabelFirst: '#phone-details-template-0 h2',
|
||||
detailsTelButtonFirst: '.button.icon-call[data-tel]',
|
||||
detailsEmail: '#contact-detail-inner #email-details-template-0 div.item',
|
||||
detailsAddress: '#contact-detail-inner #address-details-template-0 div.item',
|
||||
detailsOrg: '#contact-detail-inner #org-title',
|
||||
detailsNote: '#contact-detail-inner #note-details-template-0',
|
||||
detailsFindDuplicate: '#contact-detail-inner #find-merge-button',
|
||||
detailsFavoriteButton: '#toggle-favorite',
|
||||
detailsContactName: '#contact-name-title',
|
||||
detailsHeader: '#details-view-header',
|
||||
detailsSocialLabel: '#contact-detail-inner #details-list #social-label',
|
||||
detailsSocialTemplate: '#contact-detail-inner #details-list .social-actions',
|
||||
detailsCoverImage: '#cover-img',
|
||||
detailsShareButton: '#contact-detail-inner #share_button',
|
||||
|
||||
findDupsButton: '#details-list #find-merge-button',
|
||||
|
||||
duplicateFrame: 'iframe[src*="matching_contacts.html"]',
|
||||
duplicateHeader: '#title',
|
||||
duplicateClose: '#merge-close',
|
||||
duplicateMerge: '#merge-action',
|
||||
|
||||
exportButton: '#exportContacts button',
|
||||
exportSDCard: '#export-sd-option button',
|
||||
|
||||
form: '#view-contact-form',
|
||||
formTitle: '#contact-form-title',
|
||||
formCustomTag: '#custom-tag',
|
||||
formCustomTagPage: '#view-select-tag',
|
||||
formCustomTagDone: '#view-select-tag #settings-done',
|
||||
formNew: '#add-contact-button',
|
||||
formGivenName: '#givenName',
|
||||
formOrg: '#org',
|
||||
formFamilyName: '#familyName',
|
||||
formSave: '#save-button',
|
||||
formTel: '#contacts-form-phones input[type="tel"]',
|
||||
formDelFirstTel: '#add-phone-0 .img-delete-button',
|
||||
formTelLabelFirst: '#tel_type_0',
|
||||
formTelNumberFirst: '#number_0',
|
||||
formTelNumberSecond: '#number_1',
|
||||
formEmailFirst: '#email_0',
|
||||
formEmailSecond: '#email_1',
|
||||
formPhotoButton: '#photo-button',
|
||||
formAddNewTel: '#add-new-phone',
|
||||
formAddNewEmail: '#add-new-email',
|
||||
formHeader: '#contact-form-header',
|
||||
formPhotoImg: '#thumbnail-photo',
|
||||
deleteContact: '#delete-contact',
|
||||
|
||||
groupList: ' #groups-list',
|
||||
contacts: '#groups-list .contact-item',
|
||||
list: '#view-contacts-list',
|
||||
listContactFirst: 'li:not([data-group="ice"]).contact-item',
|
||||
listContactFirstText: 'li:not([data-group="ice"]).contact-item p',
|
||||
contactsItems: 'li:not([data-group="ice"]).contact-item p',
|
||||
contactListHeader: '#contacts-list-header',
|
||||
|
||||
contactsIframe: '#iframe-contacts',
|
||||
|
||||
searchLabel: '#search-start',
|
||||
searchInput: '#search-contact',
|
||||
searchCancel: '#cancel-search',
|
||||
searchResultFirst: '#search-list .contact-item',
|
||||
|
||||
scrollbar: 'nav[data-type="scrollbar"]',
|
||||
overlay: 'nav[data-type="scrollbar"] p',
|
||||
|
||||
settingsView: '#view-settings',
|
||||
settingsClose: '#settings-close',
|
||||
bulkDelete: '#bulkDelete',
|
||||
orderSwitch: '#settingsOrder gaia-switch',
|
||||
changeOrder: '#switch',
|
||||
|
||||
editForm: '#selectable-form',
|
||||
editMenu: '#select-all-wrapper',
|
||||
selectAction: '#select-action',
|
||||
selectAllButton: '#select-all',
|
||||
|
||||
clearOrgButton: '#clear-org',
|
||||
setIceButton: '#set-ice',
|
||||
iceHeader: '#ice-header',
|
||||
iceSettingsHeader: '#ice-settings-header',
|
||||
iceSettings: '#ice-settings',
|
||||
iceSwitch1: '#ice-contacts-1-switch',
|
||||
iceInputSwitch1: '#ice-contacts-1-switch input[type="checkbox"]',
|
||||
iceSwitch2: '#ice-contacts-2-switch',
|
||||
iceInputSwitch2: '#ice-contacts-2-switch input[type="checkbox"]',
|
||||
iceButton1: '#select-ice-contact-1',
|
||||
iceButton2: '#select-ice-contact-2',
|
||||
iceGroupOpen: '#section-group-ice',
|
||||
iceContact: '#ice-group .contact-item',
|
||||
|
||||
importContacts: '#importContacts',
|
||||
importSDCard: '#import-sd-option button',
|
||||
importHeader: '#import-settings-header',
|
||||
|
||||
activityChooser: 'form[data-type="action"]',
|
||||
buttonActivityChooser: 'form[data-type="action"] button',
|
||||
actionMenu: '#action-menu',
|
||||
actionMenuList: '#value-menu',
|
||||
actionButton: '.action-button',
|
||||
|
||||
multipleSelectSave: '#save-button',
|
||||
multipleSelectStatus: '#statusMsg p',
|
||||
multipleSelectList: '#multiple-select-container',
|
||||
|
||||
systemMenu: 'form[data-z-index-level="action-menu"]',
|
||||
|
||||
galleryImage: '.thumbnail img',
|
||||
galleryDone: '#crop-done-button',
|
||||
|
||||
header: '#edit-title',
|
||||
|
||||
noContacts: '#no-contacts'
|
||||
};
|
||||
|
||||
Contacts.prototype = {
|
||||
/**
|
||||
* Launches contacts app and focuses on frame.
|
||||
*/
|
||||
launch: function() {
|
||||
this.client.apps.launch(Contacts.URL, 'contacts');
|
||||
this.switchToApp();
|
||||
this.client.helper.waitForElement(Contacts.Selectors.bodyReady);
|
||||
},
|
||||
|
||||
relaunch: function() {
|
||||
this.close();
|
||||
this.launch();
|
||||
},
|
||||
|
||||
close: function() {
|
||||
this.client.apps.close(Contacts.URL, 'contacts');
|
||||
},
|
||||
|
||||
switchToApp: function() {
|
||||
this.client.switchToFrame();
|
||||
// switchToApp already waits for the app to be displayed
|
||||
this.client.apps.switchToApp(Contacts.URL, 'contacts');
|
||||
},
|
||||
|
||||
switchToCreateNewContactActivity: function() {
|
||||
this._switchToActivity('views/form/form.html');
|
||||
},
|
||||
|
||||
switchToMergeInterface: function() {
|
||||
this._switchToActivity('views/matching/matching_contacts.html');
|
||||
},
|
||||
|
||||
_switchToActivity: function(href) {
|
||||
this.client.switchToFrame();
|
||||
// switchToActivity already waits for the app to be displayed
|
||||
this.client.apps.switchToActivity(Contacts.URL, '/contacts/' + href);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a localized string from a properties file.
|
||||
* @param {String} file to open.
|
||||
* @param {String} key of the string to lookup.
|
||||
*/
|
||||
l10n: function(file, key) {
|
||||
var ast = this.client.executeScript(function(file, key) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
var data;
|
||||
xhr.open('GET', file, false); // Intentional sync
|
||||
xhr.onload = function(o) {
|
||||
data = JSON.parse(xhr.response);
|
||||
};
|
||||
xhr.send(null);
|
||||
return data;
|
||||
}, [file, key]);
|
||||
|
||||
for (var i = 0; i < ast.length; i++) {
|
||||
if (ast[i].$i === key) {
|
||||
return ast[i].$v;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
waitSlideLeft: function(elementKey) {
|
||||
var element = this.client.findElement(Contacts.Selectors[elementKey]),
|
||||
location;
|
||||
var test = function() {
|
||||
location = element.location();
|
||||
return location.x <= 0;
|
||||
};
|
||||
this.client.waitFor(test);
|
||||
},
|
||||
|
||||
waitForSlideDown: function(element) {
|
||||
var bodyHeight = this.client.findElement(Contacts.Selectors.body).
|
||||
size().height;
|
||||
var test = function() {
|
||||
return element.location().y >= bodyHeight;
|
||||
};
|
||||
this.client.waitFor(test);
|
||||
},
|
||||
|
||||
waitForSlideUp: function(element) {
|
||||
var test = function() {
|
||||
return element.location().y <= 0;
|
||||
};
|
||||
this.client.waitFor(test);
|
||||
},
|
||||
|
||||
waitForFadeIn: function(element) {
|
||||
var test = function() {
|
||||
var opacity = element.cssProperty('opacity');
|
||||
var pointerEvents = element.cssProperty('pointer-events');
|
||||
|
||||
return opacity == 1 && pointerEvents == 'auto';
|
||||
};
|
||||
this.client.waitFor(test);
|
||||
},
|
||||
|
||||
waitForFormShown: function() {
|
||||
var form = this.client.helper.waitForElement(Contacts.Selectors.form),
|
||||
location;
|
||||
var test = function() {
|
||||
location = form.location();
|
||||
return location.y <= 0;
|
||||
};
|
||||
this.client.waitFor(test);
|
||||
},
|
||||
|
||||
waitForFormTransition: function() {
|
||||
var selectors = Contacts.Selectors;
|
||||
var form = this.client.findElement(selectors.form);
|
||||
try {
|
||||
this.client.helper.waitForElementToDisappear(form);
|
||||
} catch (e) {
|
||||
// When the contact details pages was created in an activity and we close
|
||||
// it, we might encounter errors like "GenericError: can't access dead
|
||||
// object" or 'JavaScriptError: unload was called'. So we drop them as it
|
||||
// makes the tests crash.
|
||||
var isKnownError = e.message.indexOf(
|
||||
'GenericError: can\'t access dead object') > -1 ||
|
||||
e.message.indexOf('JavaScriptError: unload was called') > -1;
|
||||
|
||||
if (!isKnownError) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
editContact: function() {
|
||||
var selectors = Contacts.Selectors;
|
||||
|
||||
var edit = this.client.helper.waitForElement(selectors.detailsEditContact);
|
||||
this.clickOn(edit);
|
||||
this.waitForFadeIn(this.client.helper.waitForElement(selectors.form));
|
||||
},
|
||||
|
||||
// Goes back to the Contact List view from a Details view
|
||||
backToList: function() {
|
||||
var selectors = Contacts.Selectors;
|
||||
|
||||
// Now we go back to the ICE settings and check that our ICE remains
|
||||
this.waitForFadeIn(this.client.helper.waitForElement(selectors.details));
|
||||
var header = this.client.helper.waitForElement(selectors.detailsHeader);
|
||||
this.actions.wait(0.5).tap(header, 10, 10).perform();
|
||||
this.waitSlideLeft('list');
|
||||
},
|
||||
|
||||
enterContactDetails: function(details) {
|
||||
|
||||
var selectors = Contacts.Selectors;
|
||||
|
||||
details = details || {
|
||||
givenName: 'Hello',
|
||||
familyName: 'Contact',
|
||||
org: 'Enterprise'
|
||||
};
|
||||
|
||||
this.waitForFormShown();
|
||||
|
||||
for (var i in details) {
|
||||
// Camelcase details to match form.* selectors.
|
||||
var key = 'form' + i.charAt(0).toUpperCase() + i.slice(1);
|
||||
|
||||
this.client.findElement(selectors[key])
|
||||
.sendKeys(details[i]);
|
||||
}
|
||||
|
||||
this.client.findElement(selectors.formSave).click();
|
||||
},
|
||||
|
||||
addContact: function(details) {
|
||||
var selectors = Contacts.Selectors;
|
||||
|
||||
var addContact = this.client.findElement(selectors.formNew);
|
||||
addContact.click();
|
||||
|
||||
this.enterContactDetails(details);
|
||||
this.waitForFormTransition();
|
||||
|
||||
this.client.helper.waitForElement(selectors.list);
|
||||
},
|
||||
|
||||
mergeContact: function(details) {
|
||||
var selectors = Contacts.Selectors;
|
||||
|
||||
var addContact = this.client.findElement(selectors.formNew);
|
||||
addContact.click();
|
||||
|
||||
this.enterContactDetails(details);
|
||||
this.switchToMergeInterface();
|
||||
|
||||
var duplicateFrame = this.client.findElement(selectors.duplicateFrame);
|
||||
|
||||
var mergeAction =
|
||||
this.client.helper.waitForElement(selectors.duplicateMerge);
|
||||
this.clickOn(mergeAction);
|
||||
|
||||
this.switchTo();
|
||||
this.waitForSlideDown(duplicateFrame);
|
||||
},
|
||||
|
||||
addContactMultipleEmails: function(details) {
|
||||
var selectors = Contacts.Selectors;
|
||||
|
||||
var addContact = this.client.findElement(selectors.formNew);
|
||||
addContact.click();
|
||||
this.client.helper.waitForElement(selectors.formAddNewEmail).click();
|
||||
|
||||
this.enterContactDetails(details);
|
||||
this.waitForFormTransition();
|
||||
|
||||
this.client.helper.waitForElement(selectors.list);
|
||||
},
|
||||
|
||||
tapContact: function(contactName) {
|
||||
// There are currently no way to search on the text of an HTML Element
|
||||
// That's why this function do the filter and check that no more than 1
|
||||
// contact has the name we look up.
|
||||
var elements = this.client.findElements(Contacts.Selectors.contacts);
|
||||
var contactsWithName = elements.filter(function(el) {
|
||||
var data = el.text();
|
||||
return data && data.indexOf(contactName) > -1;
|
||||
});
|
||||
|
||||
if (contactsWithName.length === 1) {
|
||||
contactsWithName[0].tap();
|
||||
} else if (contactsWithName.length > 1) {
|
||||
throw new Error('There are more than 1 contact that contains "' +
|
||||
contactName + '"');
|
||||
} else {
|
||||
throw new Error('"' + contactName + '" was not found');
|
||||
}
|
||||
},
|
||||
|
||||
getContactFirstName: function() {
|
||||
var ci = this.client.findElement(Contacts.Selectors.contactsIframe);
|
||||
this.client.switchToFrame(ci);
|
||||
|
||||
var contactInContactList = this.client.findElement(
|
||||
Contacts.Selectors.listContactFirst
|
||||
);
|
||||
var contactName = contactInContactList.text();
|
||||
return contactName;
|
||||
},
|
||||
|
||||
tapSave: function() {
|
||||
this.client.helper.waitForElement(Contacts.Selectors.formSave).click();
|
||||
},
|
||||
|
||||
createNewContactAndReturnToDialer: function(contactName) {
|
||||
this.client.helper.waitForElement(Contacts.Selectors.formGivenName);
|
||||
this.client.helper.fillInputField(
|
||||
Contacts.Selectors.formGivenName, contactName
|
||||
);
|
||||
this.client.helper.waitForElement(Contacts.Selectors.formSave).click();
|
||||
|
||||
var dialer = this.client.loader.getAppClass('dialer');
|
||||
dialer.switchTo();
|
||||
return dialer;
|
||||
},
|
||||
|
||||
tapUpdate: function() {
|
||||
this.tapSave();
|
||||
},
|
||||
|
||||
get systemMenu() {
|
||||
var selectors = Contacts.Selectors;
|
||||
// Switch to the system app first.
|
||||
this.client.switchToFrame();
|
||||
return this.client.helper.waitForElement(selectors.systemMenu);
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper method to simulate clicks on iFrames which is not currently
|
||||
* working in the Marionette JS Runner.
|
||||
* @param {Marionette.Element} element The element to simulate the click on.
|
||||
**/
|
||||
clickOn: function(element) {
|
||||
element.scriptWith(function(elementEl) {
|
||||
var event = new MouseEvent('click', {
|
||||
'view': window,
|
||||
'bubbles': true,
|
||||
'cancelable': true
|
||||
});
|
||||
elementEl.dispatchEvent(event);
|
||||
});
|
||||
},
|
||||
|
||||
goToSettings: function() {
|
||||
this.client.helper.waitForElement(
|
||||
Contacts.Selectors.settingsButton).tap();
|
||||
var settings = this.client.helper.waitForElement(
|
||||
Contacts.Selectors.settingsView);
|
||||
this.waitForFadeIn(settings);
|
||||
},
|
||||
|
||||
getElementStyle: function(selector, type) {
|
||||
return this.client.executeScript(function(selector, type) {
|
||||
return document.querySelector(selector).style[type];
|
||||
}, [selector, type]);
|
||||
},
|
||||
|
||||
getNumberOfContacts: function() {
|
||||
return this.contactsNames.length;
|
||||
},
|
||||
|
||||
get contactsNames() {
|
||||
try {
|
||||
var contactElements = this.client.findElements(
|
||||
Contacts.Selectors.contactsItems);
|
||||
return contactElements.map((element) => {
|
||||
return element.text();
|
||||
});
|
||||
} catch(e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports = Contacts;
|
||||
126
gaia/apps/communications/contacts/test/marionette/lib/contacts_data.js
Executable file
126
gaia/apps/communications/contacts/test/marionette/lib/contacts_data.js
Executable file
|
|
@ -0,0 +1,126 @@
|
|||
'use strict';
|
||||
|
||||
/* globals mozContact */
|
||||
|
||||
var fs = require('fs');
|
||||
|
||||
/* This module contains Contacts Data Layer functions */
|
||||
|
||||
function ContactsData(client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
ContactsData.prototype = {
|
||||
// Creates a new FB Contact
|
||||
createFbContact: function() {
|
||||
this.client.importScript(fs.readFileSync(__dirname +
|
||||
'/../data/facebook_contact_data.js',
|
||||
'utf8'));
|
||||
|
||||
var saveFBContact = function() {
|
||||
var LazyLoader = window.wrappedJSObject.LazyLoader;
|
||||
var data = window.wrappedJSObject.data;
|
||||
var fb = window.wrappedJSObject.fb;
|
||||
var Contacts = window.wrappedJSObject.Contacts;
|
||||
|
||||
var DEPS = [
|
||||
'/shared/js/contacts/utilities/image_square.js'
|
||||
];
|
||||
Contacts.loadFacebook(function() {
|
||||
LazyLoader.load(DEPS, function() {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', '/contacts/style/images/f_logo.png');
|
||||
xhr.responseType = 'blob';
|
||||
xhr.onload = function() {
|
||||
var fbContact = new fb.Contact();
|
||||
data.fbContactData.fbInfo.photo = [xhr.response];
|
||||
fbContact.setData(data.fbContactData);
|
||||
|
||||
var savingFBContact = fbContact.save();
|
||||
|
||||
savingFBContact.onsuccess = function() {
|
||||
marionetteScriptFinished(data.fbContactData);
|
||||
};
|
||||
|
||||
savingFBContact.onerror = function() {
|
||||
marionetteScriptFinished();
|
||||
};
|
||||
};
|
||||
xhr.onerror = marionetteScriptFinished;
|
||||
xhr.send(null);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
var fbContactData;
|
||||
this.client.executeAsyncScript(saveFBContact, function(err, val) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
fbContactData = val;
|
||||
});
|
||||
|
||||
this.client.waitFor(function() {
|
||||
return fbContactData;
|
||||
});
|
||||
|
||||
return fbContactData;
|
||||
},
|
||||
|
||||
createMozContact: function(contactData, withPhoto) {
|
||||
var saveMozContact = function(contactData, withPhoto) {
|
||||
var doSave = function doSave(contactData) {
|
||||
var mozContacts = navigator.mozContacts;
|
||||
|
||||
var handler = function handler(event) {
|
||||
mozContacts.removeEventListener('contactchange', handler);
|
||||
marionetteScriptFinished(event.contactID);
|
||||
};
|
||||
|
||||
mozContacts.addEventListener('contactchange', handler);
|
||||
|
||||
var contact = new mozContact(contactData);
|
||||
var req = mozContacts.save(contact);
|
||||
|
||||
req.onerror = function() {
|
||||
mozContacts.removeEventListener('contactchange', handler);
|
||||
marionetteScriptFinished();
|
||||
};
|
||||
};
|
||||
|
||||
if (withPhoto) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', '/contacts/style/images/f_logo.png');
|
||||
xhr.responseType = 'blob';
|
||||
xhr.onload = function() {
|
||||
contactData.photo = [xhr.response];
|
||||
doSave(contactData);
|
||||
};
|
||||
xhr.onerror = marionetteScriptFinished;
|
||||
|
||||
xhr.send(null);
|
||||
}
|
||||
else {
|
||||
doSave(contactData);
|
||||
}
|
||||
};
|
||||
|
||||
var contactID;
|
||||
this.client.executeAsyncScript(saveMozContact, [contactData, withPhoto],
|
||||
function(err, val) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
}
|
||||
contactID = val;
|
||||
});
|
||||
|
||||
this.client.waitFor(function() {
|
||||
return contactID;
|
||||
});
|
||||
|
||||
return contactID;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = ContactsData;
|
||||
40
gaia/apps/communications/contacts/test/marionette/lib/sms.js
Executable file
40
gaia/apps/communications/contacts/test/marionette/lib/sms.js
Executable file
|
|
@ -0,0 +1,40 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* Abstraction around sms app.
|
||||
* This file can be moved to the sms app once we
|
||||
* implement sms marionette tests.
|
||||
* @constructor
|
||||
* @param {Marionette.Client} client for operations.
|
||||
*/
|
||||
function Sms(client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
/**
|
||||
* @type String Origin of sms app
|
||||
*/
|
||||
Sms.URL = 'app://sms.gaiamobile.org';
|
||||
|
||||
Sms.Selectors = {
|
||||
listCompose: '#icon-add',
|
||||
threadAddContact: '#messages-contact-pick-button'
|
||||
};
|
||||
|
||||
Sms.prototype = {
|
||||
/**
|
||||
* Launches sms app and focuses on frame.
|
||||
*/
|
||||
launch: function() {
|
||||
this.client.apps.launch(Sms.URL);
|
||||
this.client.apps.switchToApp(Sms.URL);
|
||||
this.client.helper.waitForElement('body');
|
||||
},
|
||||
|
||||
relaunch: function() {
|
||||
this.client.apps.close(Sms.URL);
|
||||
this.launch();
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = Sms;
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
'use strict';
|
||||
|
||||
/* global module */
|
||||
var SELECTORS = Object.freeze({
|
||||
detailsFavoriteButton: '#toggle-favorite',
|
||||
detailsHeader: '#details-view-header',
|
||||
details: '#view-contact-details',
|
||||
list: '#view-contacts-list'
|
||||
});
|
||||
|
||||
function ContactsDetailsAccessor(client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
ContactsDetailsAccessor.prototype = {
|
||||
get favoritesButton() {
|
||||
return this.client.helper.waitForElement(
|
||||
SELECTORS.detailsFavoriteButton);
|
||||
},
|
||||
|
||||
get detailsHeader() {
|
||||
return this.client.helper.waitForElement(
|
||||
SELECTORS.detailsHeader);
|
||||
},
|
||||
|
||||
get listSelector () {
|
||||
return SELECTORS.list;
|
||||
},
|
||||
|
||||
get detailsSelector () {
|
||||
return SELECTORS.details;
|
||||
},
|
||||
|
||||
get detailsHeaderSelector () {
|
||||
return SELECTORS.detailsHeader;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = ContactsDetailsAccessor;
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
'use strict';
|
||||
|
||||
/* global module */
|
||||
|
||||
var ContactsDetailsAccessor = require('./accessors');
|
||||
|
||||
function ContactsDetailsView(client) {
|
||||
this.client = client;
|
||||
this.accessors = new ContactsDetailsAccessor(client);
|
||||
}
|
||||
|
||||
ContactsDetailsView.prototype = {
|
||||
makeFavorited: function() {
|
||||
this.accessors.favoritesButton.tap();
|
||||
this.waitForFavorited;
|
||||
},
|
||||
|
||||
waitForFavorited: function() {
|
||||
var self = this;
|
||||
this.client.waitFor(
|
||||
'waitForHeaderToContainFavoriteClass', function() {
|
||||
return self.accessors.detailsHeader.getAttribute(
|
||||
'class').indexOf('favorite') != -1;
|
||||
});
|
||||
},
|
||||
//TO-DO: ADD THIS TO A CONTACT VIEW BASE CLASS
|
||||
backToList: function() {
|
||||
this.waitForFadeIn(this.client.helper.waitForElement(
|
||||
this.accessors.detailsSelector));
|
||||
var header = this.client.helper.waitForElement(
|
||||
this.accessors.detailsHeaderSelector);
|
||||
this.client.loader.getActions().wait(0.5).tap(header, 10, 10).perform();
|
||||
this.waitSlideLeftList();
|
||||
},
|
||||
|
||||
waitSlideLeftList: function() {
|
||||
var element = this.client.findElement(
|
||||
this.accessors.listSelector),
|
||||
location;
|
||||
var test = function() {
|
||||
location = element.location();
|
||||
return location.x <= 0;
|
||||
};
|
||||
this.client.waitFor(test);
|
||||
},
|
||||
|
||||
waitForFadeIn: function(element) {
|
||||
var test = function() {
|
||||
var opacity = element.cssProperty('opacity');
|
||||
var pointerEvents = element.cssProperty('pointer-events');
|
||||
return opacity == 1 && pointerEvents == 'auto';
|
||||
};
|
||||
this.client.waitFor(test);
|
||||
},
|
||||
|
||||
backtoContactsList: function() {
|
||||
this.backToList();
|
||||
var ContactsListView = require('../contact-list/view');
|
||||
var contactsListView = new ContactsListView(this.client);
|
||||
contactsListView.accessors.firstFavorite;
|
||||
return contactsListView;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports = ContactsDetailsView;
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
'use strict';
|
||||
|
||||
/* global module */
|
||||
var SELECTORS = Object.freeze({
|
||||
listContactFirstText: 'li:not([data-group="ice"]).contact-item p',
|
||||
listFavoritesFirstText: '#contacts-list-favorites .contact-item p',
|
||||
details: '#view-contact-details'
|
||||
});
|
||||
|
||||
function ContactsListAccessor(client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
ContactsListAccessor.prototype = {
|
||||
get firstContact() {
|
||||
return this.client.helper.waitForElement(
|
||||
SELECTORS.listContactFirstText);
|
||||
},
|
||||
|
||||
get firstFavorite() {
|
||||
return this.client.helper.waitForElement(
|
||||
SELECTORS.listFavoritesFirstText);
|
||||
},
|
||||
|
||||
get detailsSelector() {
|
||||
return SELECTORS.details;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports = ContactsListAccessor;
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
'use strict';
|
||||
|
||||
/* global module */
|
||||
|
||||
var ContactsListAccessor = require('./accessors');
|
||||
|
||||
function ContactsListView(client) {
|
||||
this.client = client;
|
||||
this.accessors = new ContactsListAccessor(client);
|
||||
}
|
||||
|
||||
ContactsListView.prototype = {
|
||||
get firstContact() {
|
||||
return this.accessors.firstContact;
|
||||
},
|
||||
|
||||
get firstFavorite() {
|
||||
return this.accessors.firstFavorite;
|
||||
},
|
||||
|
||||
waitSlideLeftDetails: function() {
|
||||
var element = this.client.findElement(
|
||||
this.accessors.detailsSelector),
|
||||
location;
|
||||
var waitUntilPanelReachedLeftBorder = function() {
|
||||
location = element.location();
|
||||
return location.x <= 0;
|
||||
};
|
||||
this.client.waitFor(waitUntilPanelReachedLeftBorder);
|
||||
},
|
||||
|
||||
goToContact: function() {
|
||||
this.firstContact.tap();
|
||||
this.waitSlideLeftDetails();
|
||||
return this._createContactsDetailsView();
|
||||
},
|
||||
|
||||
_createContactsDetailsView: function() {
|
||||
var ContactsDetailsView = require('../contact-details/view');
|
||||
var contactsDetailsView = new ContactsDetailsView(
|
||||
this.client, this.subject);
|
||||
return contactsDetailsView;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports = ContactsListView;
|
||||
Loading…
Reference in a new issue