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:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,16 @@
{
"extends": "../../../../.jshintrc",
"node": true,
"predef": [
"suite",
"test",
"setup",
"teardown",
"suiteSetup",
"suiteTeardown",
"marionette",
"marionetteScriptFinished",
"module",
"sinon"
]
}

View file

@ -0,0 +1,273 @@
'use strict';
var AppStoragePanel = require('./regions/app_storage');
var AppPermissionPanel = require('./regions/app_permission');
var Base = require('./base');
var BatteryPanel = require('./regions/battery');
var BluetoothPanel = require('./regions/bluetooth');
var BrowsingPrivacyPanel = require('./regions/browsing_privacy');
var DateTimePanel = require('./regions/date_time');
var DeveloperPanel = require('./regions/developer');
var DeviceInfoPanel = require('./regions/device_info');
var DisplayPanel = require('./regions/display');
var DoNotTrackPanel = require('./regions/do_not_track');
var FeedbackPanel = require('./regions/feedback');
var HotspotPanel = require('./regions/hotspot');
var HotspotSettingsPanel = require('./regions/hotspot_settings');
var ImprovePanel = require('./regions/improve');
var KeyboardPanel = require('./regions/keyboard');
var LanguagePanel = require('./regions/language');
var MediaStoragePanel = require('./regions/media_storage');
var MessagePanel = require('./regions/message');
var NotificationsPanel = require('./regions/notifications');
var RootPanel = require('./regions/root');
var ScreenLockPanel = require('./regions/screen_lock');
var SoundPanel = require('./regions/sound');
var SupportPanel = require('./regions/support');
var UsbStoragePanel = require('./regions/usb_storage');
/**
* Abstraction around settings app
* @constructor
* @param {Marionette.Client} client for operations.
*/
function Settings(client) {
this.client = client;
// Call the Base constructor to initiate base class.
Base.call(this, this.client, Settings.ORIGIN, Settings.Selectors);
}
// origin of the settings app
Settings.ORIGIN = 'app://settings.gaiamobile.org';
module.exports = Settings;
Settings.Selectors = {
'menuItemsSection': '#root',
'appPermissionMenuItem': '#menuItem-appPermissions',
'appStorageMenuItem': '.menuItem-applicationStorage',
'batteryMenuItem': '.menuItem-battery',
'bluetoothMenuItem': '#menuItem-bluetooth',
'browsingPrivacyMenuItem': '#menuItem-browsingPrivacy',
'dateTimeMenuItem': '#menuItem-dateAndTime',
'developerMenuItem': '#menuItem-developer',
'deviceInfoMenuItem': '#menuItem-deviceInfo',
'displayMenuItem': '#menuItem-display',
'doNotTrackMenuItem': '#menuItem-doNotTrack',
'feedbackMenuItem': 'a[href="#improveBrowserOS-chooseFeedback"]',
'hotspotMenuItem': '#menuItem-internetSharing',
'hotspotPanel': '#hotspot',
'hotspotSettingsTrigger': '#hotspot-settings-section button',
'improveMenuItem': '#menuItem-improveBrowserOS',
'improveSection': '#improveBrowserOS',
'keyboardMenuItem': '#menuItem-keyboard',
'languageMenuItem': '.menuItem-languageAndRegion',
'mediaStorageMenuItem': '.menuItem-mediaStorage',
'messageMenuItem': '#menuItem-messagingSettings',
'notificationsMenuItem': '#menuItem-notifications',
'screenLockMenuItem': '#menuItem-screenLock',
'soundMenuItem': '#menuItem-sound',
'supportMenuItem': '#menuItem-help',
'usbStorageMenuItem': '.menuItem-enableStorage'
};
Settings.prototype = {
__proto__: Base.prototype,
get rootPanel() {
this._rootPanel = this._rootPanel ||
new RootPanel(this.client);
return this._rootPanel;
},
get bluetoothPanel() {
this.openPanel('bluetoothMenuItem');
this._bluetoothPanel = this._bluetoothPanel ||
new BluetoothPanel(this.client);
return this._bluetoothPanel;
},
get doNotTrackPanel() {
this.openPanel('doNotTrackMenuItem');
this._doNotTrackPanel = this._doNotTrackPanel ||
new DoNotTrackPanel(this.client);
return this._doNotTrackPanel;
},
get browsingPrivacyPanel() {
this.openPanel('browsingPrivacyMenuItem');
this._browsingPrivacyPanel = this._browsingPrivacyPanel ||
new BrowsingPrivacyPanel(this.client);
return this._browsingPrivacyPanel;
},
get hotspotPanel() {
this.openPanel('hotspotMenuItem');
this._hotspotPanel = this._hotspotPanel ||
new HotspotPanel(this.client);
return this._hotspotPanel;
},
get hotspotSettingsPanel() {
this.openPanel('hotspotSettingsTrigger', 'hotspotPanel');
this._hotspotSettingsPanel = this._hotspotSettingsPanel ||
new HotspotSettingsPanel(this.client);
return this._hotspotSettingsPanel;
},
get supportPanel() {
this.openPanel('supportMenuItem');
this._supportPanel = this._supportPanel ||
new SupportPanel(this.client);
return this._supportPanel;
},
get batteryPanel() {
this.openPanel('batteryMenuItem');
this._batteryPanel = this._batteryPanel ||
new BatteryPanel(this.client);
return this._batteryPanel;
},
get dateTimePanel() {
this.openPanel('dateTimeMenuItem');
this._dateTimePanel = this._dateTimePanel ||
new DateTimePanel(this.client);
return this._dateTimePanel;
},
get notificationsPanel() {
this.openPanel('notificationsMenuItem');
this._notificationsPanel = this._notificationsPanel ||
new NotificationsPanel(this.client);
return this._notificationsPanel;
},
get soundPanel() {
this.openPanel('soundMenuItem');
this._soundPanel = this._soundPanel ||
new SoundPanel(this.client);
return this._soundPanel;
},
get languagePanel() {
this.openPanel('languageMenuItem');
this._languagePanel = this._languagePanel ||
new LanguagePanel(this.client);
return this._languagePanel;
},
get screenLockPanel() {
this.openPanel('screenLockMenuItem');
this._screenLockPanel = this._screenLockPanel ||
new ScreenLockPanel(this.client);
return this._screenLockPanel;
},
get displayPanel() {
this.openPanel.call(this, 'displayMenuItem');
this._displayPanel = this._displayPanel ||
new DisplayPanel(this.client);
return this._displayPanel;
},
get improvePanel() {
this.openPanel.call(this, 'improveMenuItem');
this._improvePanel = this._improvePanel ||
new ImprovePanel(this.client);
return this._improvePanel;
},
get feedbackPanel() {
this.openPanel.call(this, 'feedbackMenuItem', 'improveSection');
this._feedbackPanel =
this._feedbackPanel || new FeedbackPanel(this.client);
return this._feedbackPanel;
},
get appPermissionPanel() {
this.openPanel.call(this, 'appPermissionMenuItem');
this._appPermissionPanel =
this._appPermissionPanel || new AppPermissionPanel(this.client);
return this._appPermissionPanel;
},
get appStoragePanel() {
this.openPanel.call(this, 'appStorageMenuItem');
this._appStoragePanel =
this._appStoragePanel || new AppStoragePanel(this.client);
return this._appStoragePanel;
},
get mediaStoragePanel() {
this.openPanel('mediaStorageMenuItem');
this._mediaStoragePanel = this._mediaStoragePanel ||
new MediaStoragePanel(this.client);
return this._mediaStoragePanel;
},
get keyboardPanel() {
this.openPanel('keyboardMenuItem');
this._keyboardPanel = this._keyboardPanel || new KeyboardPanel(this.client);
return this._keyboardPanel;
},
get messagePanel() {
this.openPanel('messageMenuItem');
this._messagePanel = this._messagePanel || new MessagePanel(this.client);
return this._messagePanel;
},
get aboutPanel() {
this.openPanel('deviceInfoMenuItem');
this._aboutPanel = this._aboutPanel ||
new DeviceInfoPanel(this.client);
return this._aboutPanel;
},
get developerPanel() {
this.openPanel('developerMenuItem');
this._developerPanel = this._developerPanel ||
new DeveloperPanel(this.client);
return this._developerPanel;
},
get usbStoragePanel() {
this.openPanel('usbStorageMenuItem');
this._usbStoragePanel = this._usbStoragePanel ||
new UsbStoragePanel(this.client);
return this._usbStoragePanel;
},
set currentLanguage(value) {
// open the language panel
var languagePanel = this.languagePanel;
languagePanel.currentLanguage = value;
languagePanel.back();
},
/**
* @private
*/
openPanel: function app_openPanel(selector, parentSelector) {
var localParentSelector = parentSelector || 'menuItemsSection';
var menuItem = this.waitForElement(selector);
var parentSection = this.waitForElement(localParentSelector);
// make sure it is enabled first
this.client.waitFor(function() {
return this.findElement('messageMenuItem').enabled();
}.bind(this));
menuItem.scriptWith(function(el) {
el.scrollIntoView(false);
});
menuItem.tap();
this.client.waitFor(function() {
var loc = parentSection.location();
var size = parentSection.size();
return Math.abs(loc.x) === size.width;
});
}
};

View file

@ -0,0 +1,89 @@
'use strict';
/**
* Base app object to provide common methods to app objects
* @constructor
* @param {Marionette.Client} client for operations.
*/
function Base(client, origin, selectors) {
this.client = client.scope({ searchTimeout: 20000 });
this.origin = origin;
this.selectors = selectors;
}
module.exports = Base;
Base.prototype = {
/**
* Launches settings app, switches to frame, and waits for it to be loaded.
*/
launch: function() {
this.client.apps.launch(this.origin);
this.client.apps.switchToApp(this.origin);
this.client.helper.waitForElement('body[data-ready="true"]');
},
/**
* Switches back to the current app frame.
* Useful when switching to system frame during test and needs to switch back.
*/
switchTo: function() {
this.client.switchToFrame();
this.client.apps.switchToApp(this.origin);
},
/**
* Close settings app.
*/
close: function() {
this.client.apps.close(this.origin);
},
/**
* @protected
* @param {String} name of selector [its a key in Settings.Selectors].
*/
findElement: function(name) {
return this.client.findElement(this.selectors[name]);
},
/**
* @protected
* @param {String} name of selector [its a key in Settings.Selectors].
*/
findElements: function(name) {
return this.client.findElements(this.selectors[name]);
},
/**
* @protected
* @param {String} name of selector [its a key in Settings.Selectors].
*/
waitForElement: function(name) {
var element = this.client.helper.waitForElement(this.selectors[name]);
this.client.waitFor(function() {
return element.scriptWith(function(el) {
var style = window.getComputedStyle(el);
return style.visibility === 'visible';
});
}.bind(this));
return element;
},
/**
* Use to select an options as currently we are not able to tap on a select
* element. Please refer to bug 977522 for details.
*
* @protected
* @param {String} name of selector [its a key in Settings.Selectors].
* @param {String} text content of an option
*/
tapSelectOption: function(name, optionText) {
this.client.helper.tapSelectOption(this.selectors[name], optionText);
},
tapConfirmButton: function() {
this.client.helper.waitForElement(
'#settings-confirm-dialog button[type="submit"]').tap();
}
};

View file

@ -0,0 +1,83 @@
'use strict';
var Base = require('./base');
/**
* Abstraction around keyboard app
* @constructor
* @param {Marionette.Client} client for operations.
*/
function KeyboardApp(client) {
Base.call(this, client, null, KeyboardApp.Selectors);
}
module.exports = KeyboardApp;
KeyboardApp.Selectors = {
'settingsHeader': '#general-header',
'vibrationCheckbox': '#cb-vibration'
};
KeyboardApp.SETTINGS_LAUNCH_PATH = 'app://keyboard.gaiamobile.org/' +
'settings.html';
KeyboardApp.prototype = {
__proto__: Base.prototype,
get vibrationFromMozSettings() {
return this.client.settings.get('keyboard.vibration');
},
switchToSettings: function() {
this.client.switchToFrame();
var settingsFrame = this.client.findElement(
'iframe[src*="' + KeyboardApp.SETTINGS_LAUNCH_PATH + '"]');
/**
* XXX: Workaround to wait for the frame is ready after switching to the
* keyboard app's settings page. We should use
* this.client.apps.switchToApp(KeyboardApp.SETTINGS_LAUNCH_PATH)
* instead of the logic below after Bug 1027994 is fixed.
*
* Add swithToApp waiting logic here, see Bug 1003788 for a similar
* technique we implemented in marionette-apps plugin.
*/
// Wait for the iframe is rendered.
this.client.waitFor(function() {
var frameClass = settingsFrame.scriptWith(function(el) {
return el.parentNode.getAttribute('class');
});
if (frameClass !== null) {
return frameClass.indexOf('render') !== -1;
} else {
return true;
}
});
// Wait for the iframe is displayed on screen.
this.client.waitFor(function() {
var transitionState = settingsFrame.scriptWith(function(el) {
return el.parentNode.getAttribute('transition-state');
});
if (transitionState !== null) {
return transitionState === 'opened';
} else {
return settingsFrame.displayed();
}
});
this.client.switchToFrame(settingsFrame);
},
clickVibrationOption: function() {
this.waitForElement('vibrationCheckbox').click();
},
goBackToSettingsApp: function() {
var header = this.waitForElement('settingsHeader');
header.tap(25, 25);
}
};

View file

@ -0,0 +1,55 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings app permission panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function AppPermissionPanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, AppPermissionPanel.Selectors);
}
module.exports = AppPermissionPanel;
AppPermissionPanel.Selectors = {
'appListItem': '.app-list a',
'geolocationSelect': 'select[data-perm="geolocation"]',
'uninstallButton': '.uninstall-app > button'
};
AppPermissionPanel.prototype = {
__proto__: Base.prototype,
permissionTable: {
'Grant': 'allow'
},
get georlocationSelectValue() {
return this.findElement('geolocationSelect').getAttribute('value');
},
get appList() {
return this.findElements('appListItem');
},
get uninstallButton() {
return this.waitForElement('uninstallButton');
},
tapGeolocationSelect: function(value) {
this.tapSelectOption('geolocationSelect', value);
},
enterPermissionDetail: function() {
var entry = this.waitForElement('appListItem');
entry.tap();
this.client.waitFor(function() {
return this.findElement('geolocationSelect');
}.bind(this));
}
};

View file

@ -0,0 +1,44 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings app storage panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function AppStoragePanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, AppStoragePanel.Selectors);
}
function hasNumbers(t) {
return /\d/.test(t);
}
module.exports = AppStoragePanel;
AppStoragePanel.Selectors = {
'appTotalSpace': '.apps-total-space',
'appUsedSpace': '.apps-used-space',
'appFreeSpace': '.apps-free-space'
};
AppStoragePanel.prototype = {
__proto__: Base.prototype,
get containNumberInAppTotalSpace() {
return hasNumbers(this.waitForElement('appTotalSpace').text());
},
get containNumberInAppUsedSpace() {
return hasNumbers(this.waitForElement('appUsedSpace').text());
},
get containNumberInAppFreeSpace() {
return hasNumbers(this.waitForElement('appFreeSpace').text());
}
};

View file

@ -0,0 +1,61 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings battery panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function BatteryPanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, BatteryPanel.Selectors);
}
module.exports = BatteryPanel;
BatteryPanel.Selectors = {
'powerSaveModeEnabledCheckbox': '#battery gaia-switch',
'threshold': 'select[name="powersave.threshold"]',
'option': 'option'
};
BatteryPanel.prototype = {
__proto__: Base.prototype,
get isPowerSavingEnabled() {
return this.findElement('powerSaveModeEnabledCheckbox')
.scriptWith(function(el) {
return el.wrappedJSObject.checked;
});
},
get isLastOptionSelected() {
var options = this.findElements('option');
return options[options.length - 1].getAttribute('checked');
},
changeTurnOnPeriod: function() {
this.waitForElement('threshold').tap();
this.client.waitFor(function() {
return this.isLastOptionSelected;
}.bind(this));
},
enablePowerSaveMode: function() {
this.waitForElement('powerSaveModeEnabledCheckbox').click();
this.client.waitFor(function() {
return this.isPowerSavingEnabled;
}.bind(this));
},
disablePowerSaveMode: function() {
this.waitForElement('powerSaveModeEnabledCheckbox').click();
this.client.waitFor(function() {
return !this.isPowerSavingEnabled;
}.bind(this));
}
};

View file

@ -0,0 +1,47 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings bluetooth panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function BluetoothPanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, BluetoothPanel.Selectors);
}
module.exports = BluetoothPanel;
BluetoothPanel.Selectors = {
'bluetoothEnabledCheckbox': '.bluetooth-status gaia-switch'
};
BluetoothPanel.prototype = {
__proto__: Base.prototype,
get isBluetoothEnabled() {
return this.findElement('bluetoothEnabledCheckbox')
.scriptWith(function(el) {
return el.wrappedJSObject.checked;
});
},
enableBluetooth: function() {
this.waitForElement('bluetoothEnabledCheckbox').tap();
this.client.waitFor(function() {
return this.isBluetoothEnabled;
}.bind(this));
},
disableBluetooth: function() {
this.waitForElement('bluetoothEnabledCheckbox').tap();
this.client.waitFor(function() {
return !this.isBluetoothEnabled;
}.bind(this));
}
};

View file

@ -0,0 +1,115 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings browsing privacy panel.
* @constructor
* @param {Marionette.Client} client for operations.
*/
function BrowsingPrivacyPanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, BrowsingPrivacyPanel.Selectors);
}
module.exports = BrowsingPrivacyPanel;
BrowsingPrivacyPanel.Selectors = {
'privateBrowsingSwitch':
'#browsingPrivacy gaia-switch[name="browser.private.default"]',
'trackingProtectionEnabledSwitch':
'#browsingPrivacy gaia-switch[name="privacy.trackingprotection.enabled"]',
'clearHistoryButton':
'#browsingPrivacy .clear-history-button',
'clearPrivateDataButton':
'#browsingPrivacy .clear-private-data-button',
'confirmDialog':
'#settings-confirm-dialog',
'confirmDialogCancel':
'#settings-confirm-dialog button[type="reset"]',
'confirmDialogSubmit':
'#settings-confirm-dialog button[type="submit"]'
};
BrowsingPrivacyPanel.prototype = {
__proto__: Base.prototype,
get isPrivateBrowsingEnabled() {
return this.findElement('privateBrowsingSwitch')
.scriptWith(function(el) {
return el.wrappedJSObject.checked;
});
},
get isTrackingProtectionEnabled() {
return this.findElement('trackingProtectionEnabledSwitch')
.scriptWith(function(el) {
return el.wrappedJSObject.checked;
});
},
get confirmDialogShown() {
return this.findElement('confirmDialog').displayed();
},
enablePrivateBrowsing: function() {
if (this.isPrivateBrowsingEnabled) {
return;
}
this.waitForElement('privateBrowsingSwitch').click();
this.client.waitFor(function() {
return this.isPrivateBrowsingEnabled;
}.bind(this));
},
enableTrackingProtection: function() {
if (this.isTrackingProtectionEnabled) {
return;
}
this.waitForElement('trackingProtectionEnabledSwitch').click();
this.client.waitFor(function() {
return this.isTrackingProtectionEnabled;
}.bind(this));
},
disableTrackingProtection: function() {
if (!this.isTrackingProtectionEnabled) {
return;
}
this.waitForElement('trackingProtectionEnabledSwitch').click();
this.client.waitFor(function() {
return !this.isTrackingProtectionEnabled;
}.bind(this));
},
clickClearHistoryButton: function() {
this.waitForElement('clearHistoryButton').click();
this.client.waitFor(function() {
return this.confirmDialogShown;
}.bind(this));
},
clickClearPrivateDataButton: function() {
this.waitForElement('clearPrivateDataButton').click();
this.client.waitFor(function() {
return this.confirmDialogShown;
}.bind(this));
},
clickConfirmDialogCancel: function() {
this.waitForElement('confirmDialogCancel').click();
this.client.waitFor(function() {
return !this.confirmDialogShown;
}.bind(this));
},
clickConfirmDialogSubmit: function() {
this.waitForElement('confirmDialogSubmit').click();
this.client.waitFor(function() {
return !this.confirmDialogShown;
}.bind(this));
}
};

View file

@ -0,0 +1,40 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings date time panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function DateTimePanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, DateTimePanel.Selectors);
}
module.exports = DateTimePanel;
DateTimePanel.Selectors = {
'timezoneRegion': '#dateTime .timezone-region',
'timezoneInfoText': '#dateTime .timezone-info-text',
'timeFormatSelect': '#dateTime .time-format-time'
};
DateTimePanel.prototype = {
__proto__: Base.prototype,
selectRegion: function(value) {
this.tapSelectOption('timezoneRegion', value);
},
selectTimeFormat: function(value) {
this.tapSelectOption('timeFormatSelect', value);
},
get timezoneInfoText() {
return this.waitForElement('timezoneInfoText').text();
}
};

View file

@ -0,0 +1,29 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings developer panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function DeveloperPanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, DeveloperPanel.Selectors);
}
module.exports = DeveloperPanel;
DeveloperPanel.Selectors = {
'DeveloperPanel': '#developer'
};
DeveloperPanel.prototype = {
__proto__: Base.prototype,
get isDeveloperMenuItemVisible() {
return this.findElement('developerMenuItem').displayed();
}
};

View file

@ -0,0 +1,112 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings media storage panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function DeviceInfoPanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, DeviceInfoPanel.Selectors);
}
module.exports = DeviceInfoPanel;
DeviceInfoPanel.Selectors = {
'moreInfoBtn': '#about a[href="#about-moreInfo"]',
'yourRightsBtn': '#about a[href="#about-yourRights"]',
'yourPrivacyBtn': '#about a[href="#about-yourPrivacy"]',
'legalInfoBtn': '#about a[href="#about-legal"]',
'resetPhoneBtn': '#about button.reset-phone',
'resetPhoneDialog': '.reset-phone-dialog',
'cancelResetPhoneBtn': '.cancel-reset-phone',
'developerMenuCheckbox': 'gaia-switch[name="developer.menu.enabled"]',
'openSourceNoticesLink': 'a[href="#about-licensing"]',
'obtainingSourceCodeLink': 'a[href="#about-source-code"]',
'privacyLink': 'a.privacy-browserOS',
'developerMenuItem': 'li > #menuItem-developer',
'aboutPanel': '#about',
'rootPanel': '#root',
'deviceInfoBackBtn': '#about gaia-header',
'moreInfoBackBtn': '#about-moreInfo gaia-header',
'openSourceNoticesBackBtn': '#about-licensing gaia-header'
};
DeviceInfoPanel.prototype = {
__proto__: Base.prototype,
tapOnResetPhoneButton: function() {
this.waitForElement('resetPhoneBtn').tap();
},
tapOnCancelResetPhoneButton: function() {
this.waitForElement('cancelResetPhoneBtn').tap();
},
get isResetPhoneDialogVisible() {
return this.findElement('resetPhoneDialog').displayed();
},
tapOnMoreInfoButton: function() {
this.waitForElement('moreInfoBtn').tap();
},
tapOnYourRightsButton: function() {
this.waitForElement('yourRightsBtn').tap();
},
tapOnYourPrivacyButton: function() {
this.waitForElement('yourPrivacyBtn').tap();
},
tapOnPrivacyBrowserButton: function() {
this.waitForElement('privacyLink').tap();
},
tapOnLegalInfoButton: function() {
this.waitForElement('legalInfoBtn').tap();
},
tapOnOpenSourceNoticesButton: function() {
this.waitForElement('openSourceNoticesLink').tap();
},
tapOnObtainingSourceCodeButton: function() {
this.waitForElement('obtainingSourceCodeLink').tap();
},
triggerDevelopMenu: function() {
this.waitForElement('developerMenuCheckbox').click();
this.client.waitFor(function() {
return this.isDevelopMenuEnabled;
}.bind(this));
},
get isDevelopMenuEnabled() {
return this.findElement('developerMenuCheckbox')
.scriptWith(function(el) {
return el.wrappedJSObject.checked;
});
},
get isDeveloperMenuItemVisible() {
return this.findElement('developerMenuItem').displayed();
},
tapDeviceInfoBackBtn: function() {
this.client.helper.wait(300);
this.waitForElement('deviceInfoBackBtn').tap(25, 25);
},
tapMoreInfoBackBtn: function() {
this.client.helper.wait(300);
this.waitForElement('moreInfoBackBtn').tap(25, 25);
},
tapOpenSourceNoticesBackBtn: function() {
this.waitForElement('openSourceNoticesBackBtn').tap(25, 25);
}
};

View file

@ -0,0 +1,85 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings display panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function DisplayPanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, DisplayPanel.Selectors);
}
module.exports = DisplayPanel;
DisplayPanel.Selectors = {
'lockOrientationCheckbox':
'#display gaia-switch[name="screen.orientation.lock"]',
'autoBrightnessItem': '.brightness-auto',
'autoBrightnessCheckbox':
'#display gaia-checkbox[name="screen.automatic-brightness"]',
'manualBrightnessItem': '.brightness-manual',
'screenTimeoutSelectorItem': '#screen-timeout',
'screenTimeoutSelector': '#screen-timeout select'
};
DisplayPanel.prototype = {
__proto__: Base.prototype,
get isLockOrientationChecked() {
// Marionette has trouble returning custom properties on shadow roots.
// For now query the shadowRoot for checked status.
return this.findElement('lockOrientationCheckbox')
.scriptWith(function(el) {
return el.shadowRoot.querySelector('input[type="checkbox"]').checked;
});
},
get isAutoBrightnessChecked() {
return !!this.findElement('autoBrightnessCheckbox')
.scriptWith(function(el) {
return el.wrappedJSObject.checked;
});
},
get isAutoBrightnessItemVisible() {
return this.findElement('autoBrightnessItem').displayed();
},
get isBrightnessManualItemVisible() {
return this.findElement('manualBrightnessItem').displayed();
},
get autoBrightnessSetting() {
return this.client.settings.get('screen.automatic-brightness');
},
get screenOrientationSetting() {
return this.client.settings.get('screen.orientation.lock');
},
get screenTimeoutSetting() {
return this.client.settings.get('screen.timeout');
},
tapLockOrientationCheckbox: function() {
this.waitForElement('lockOrientationCheckbox').tap();
},
tapAutoBrightnessCheckbox: function() {
this.waitForElement('autoBrightnessCheckbox').tap();
},
tapScreenTimeoutSelector: function() {
this.waitForElement('screenTimeoutSelectorItem').tap();
},
tapScreenTimeoutSelectOption: function(optionText) {
this.tapSelectOption('screenTimeoutSelector', optionText);
}
};

View file

@ -0,0 +1,47 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings do not track panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function DoNotTrackPanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, DoNotTrackPanel.Selectors);
}
module.exports = DoNotTrackPanel;
DoNotTrackPanel.Selectors = {
'doNotTrackEnabledCheckbox': '#doNotTrack gaia-radio'
};
DoNotTrackPanel.prototype = {
__proto__: Base.prototype,
get isDoNotTrackEnabled() {
return this.findElement('doNotTrackEnabledCheckbox')
.scriptWith(function(el) {
return el.wrappedJSObject.checked;
});
},
enableDoNotTrack: function() {
this.waitForElement('doNotTrackEnabledCheckbox').click();
this.client.waitFor(function() {
return this.isDoNotTrackEnabled;
}.bind(this));
},
disableDoNotTrack: function() {
this.waitForElement('doNotTrackEnabledCheckbox').click();
this.client.waitFor(function() {
return !this.isDoNotTrackEnabled;
}.bind(this));
}
};

View file

@ -0,0 +1,98 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings improve panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function FeedbackPanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, FeedbackPanel.Selectors);
}
module.exports = FeedbackPanel;
FeedbackPanel.Selectors = {
'feedbackPanel': '#improveBrowserOS-chooseFeedback',
'feedbackHappy': '#feedback-happy',
'feedbackSad': '#feedback-sad',
'sendFeedbackPanel': '#improveBrowserOS-sendFeedback',
'chooseFeedbackPanel': '#improveBrowserOS-chooseFeedback',
'feedbackDiscription': '#feedback-description',
'feedbackEmailEnable': '#feedback-contactyou',
'emailEnable': 'span[data-l10n-id="feedback-contactyou"]',
'feedbackEmail': '#feedback-email',
'feedbackEmailBar': '#feedback-emailbar',
'sendFeedbackButton': '#feedback-send-btn',
'alertDialogMsg': '#settings-alert-dialog.current .settings-dialog-message',
'feedbackBackButton': '#feedback-back-button'
};
FeedbackPanel.prototype = {
__proto__: Base.prototype,
get alertMsg() {
return this.waitForElement('alertDialogMsg').text();
},
get discription() {
return this.waitForElement('feedbackDiscription')
.getAttribute('value');
},
isRendered: function() {
this.client.waitFor(function() {
return this.waitForElement('feedbackPanel')
.getAttribute('data-rendered') === 'true';
}.bind(this));
},
tapFeedbackBack: function() {
this.waitForElement('feedbackBackButton').tap();
this.client.waitFor(function() {
return this.waitForElement('feedbackHappy').displayed();
}.bind(this));
},
enterWithHappy: function() {
this.waitForElement('feedbackHappy').tap();
this.sendFeedbackPanelDisplay();
},
enterWithSad: function() {
this.waitForElement('feedbackSad').tap();
this.sendFeedbackPanelDisplay();
},
sendFeedbackPanelDisplay: function() {
var chooseFeedbackPanel =
this.waitForElement('chooseFeedbackPanel');
this.client.waitFor(function() {
return chooseFeedbackPanel.location().x +
chooseFeedbackPanel.size().width === 0;
});
},
sendFeedback: function() {
this.waitForElement('sendFeedbackButton').tap();
},
openEmailCol: function() {
this.findElement('feedbackEmailEnable').click();
this.client.waitFor(function() {
var value = this.findElement('feedbackEmailBar').
getAttribute('hidden');
return value === 'false';
}.bind(this));
},
inputMsgToDialog: function(text) {
var ele = this.waitForElement('feedbackDiscription');
ele.sendKeys(text);
}
};

View file

@ -0,0 +1,25 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings hotspot panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function HotspotPanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, HotspotPanel.Selectors);
}
module.exports = HotspotPanel;
HotspotPanel.Selectors = {
};
HotspotPanel.prototype = {
__proto__: Base.prototype
};

View file

@ -0,0 +1,50 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around hotspot settings panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function HotspotSettingsPanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, HotspotSettingsPanel.Selectors);
}
module.exports = HotspotSettingsPanel;
HotspotSettingsPanel.Selectors = {
'body': 'body',
'hotspotSettingsPanel': '#hotspot-wifiSettings',
'hotspotSettingsNetworkName': 'input[data-setting="tethering.wifi.ssid"]',
'hotspotSettingsBack': '#hotspot-wifiSettings button[type="reset"]'
};
HotspotSettingsPanel.prototype = {
__proto__: Base.prototype,
get ssid() {
return this.findElement('hotspotSettingsNetworkName')
.getAttribute('value');
},
set ssid(value) {
return this.findElement('hotspotSettingsNetworkName')
.sendKeys(value);
},
back: function() {
var parentSection = this.waitForElement('hotspotSettingsPanel');
this.findElement('hotspotSettingsBack').tap();
var bodyWidth = this.findElement('body').size().width;
this.client.waitFor(function() {
var loc = parentSection.location();
return loc.x >= bodyWidth;
});
}
};

View file

@ -0,0 +1,70 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings improve panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function ImprovePanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, ImprovePanel.Selectors);
}
module.exports = ImprovePanel;
ImprovePanel.Selectors = {
'feedbackEntryButton':
'#improveBrowserOS-chooseFeedback',
'alwaysSendReport':
'#menuItem-alwaysSendReport gaia-radio',
'neverSendReport':
'#menuItem-neverSendReport gaia-radio',
'askEachTime':
'#menuItem-askToSendReport2 gaia-radio',
'reportCrashes':
'gaia-radio[name="app.reportCrashes"]'
};
ImprovePanel.prototype = {
__proto__: Base.prototype,
selectedReport: function(type) {
this.client.waitFor(function() {
var eles = this.findElements('reportCrashes');
for (var i = 0; i < eles.length; i++) {
var ele = eles[i];
if (ele.getAttribute('checked') &&
(ele.getAttribute('value') === type)) {
return true;
}
}
}.bind(this));
},
enableNeverSendReport: function() {
this.waitForElement('neverSendReport').tap();
this.selectedReport('never');
},
enableAskEachTime: function() {
this.waitForElement('askEachTime').tap();
this.selectedReport('ask');
},
enableAlwaysSendReport: function() {
this.waitForElement('alwaysSendReport').tap();
this.selectedReport('always');
},
enterFeedbackPanel: function() {
this.waitForElement('feedbackEntryButton').tap();
}
};

View file

@ -0,0 +1,62 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings keyboard panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function KeyboardPanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, KeyboardPanel.Selectors);
}
module.exports = KeyboardPanel;
KeyboardPanel.Selectors = {
keyboardList: '.allKeyboardList li',
header: '#keyboard gaia-header',
panel: '#keyboard',
selectKeyboards: '#keyboard a[href="#keyboard-selection-addMore"]',
builtinKeyboardList: '#keyboard-selection-addMore .keyboardAppContainer ul',
backButton: '#keyboard-selection-addMore gaia-header'
};
KeyboardPanel.prototype = {
__proto__: Base.prototype,
get header() {
return this.findElement('header');
},
tapBuiltInKeyboardItem: function() {
this.waitForElement('keyboardList').tap();
},
tapSelectKeyboards: function() {
this.waitForElement('selectKeyboards').tap();
},
selectLayout: function(layoutLabel) {
var builtinKeyboardList = this.waitForElement('builtinKeyboardList');
var layout = builtinKeyboardList.scriptWith(function(list, layoutLabel) {
var langs = list.querySelectorAll('bdi');
return [].filter.call(langs, function(lang) {
return (lang.innerHTML === layoutLabel);
})[0];
}, [layoutLabel]);
layout.tap();
},
tapBackButton: function() {
var header = this.waitForElement('backButton');
header.tap(25, 25);
},
isDialog: function() {
var dialogAttribute =
this.findElement('panel').getAttribute('data-dialog');
return dialogAttribute === 'true';
}
};

View file

@ -0,0 +1,134 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings do not track panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function LanguagePanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, LanguagePanel.Selectors);
}
module.exports = LanguagePanel;
LanguagePanel.Selectors = {
'languagePanel': '#languages',
'body': 'body',
'header': 'gaia-header',
'languageChangeSelect': '#languages select[name="language.current"]',
'languageLabel': 'p[data-l10n-id="language"]',
'languageRegionDateLabel': '#region-date'
};
LanguagePanel.prototype = {
__proto__: Base.prototype,
// The \u202a, \u202b and \u202c are special Unicode formatting codes which
// force the direction of the text between them. They are added by
// LanguageList.wrapBidi to ensure proper display of all language names.
_languageMap: {
english: {
label: 'Language',
desc: '\u202aEnglish (US)\u202c',
dayRules: /Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday/
},
accented: {
label: 'Ŀȧȧƞɠŭŭȧȧɠḗḗ',
desc: '\u202aƤȧȧƈķȧȧɠḗḗḓ Ȧȧƈƈḗḗƞŧḗḗḓ\u202c',
dayRules: new RegExp(
'lundi|' +
'mardi|' +
'mercredi|' +
'jeudi|' +
'vendredi|' +
'samedi|' +
'dimanche')
},
bidi: {
label: '\u202e˥ɐuƃnɐƃǝ\u202c',
desc: '\u202b\u202eԀɐɔʞɐƃǝp\u202c \u202eԐıpı\u202c\u202c',
dayRules: new RegExp(
'الاثنين|' +
'الثلاثاء|' +
'الأربعاء|' +
'الخميس|' +
'الجمعة|' +
'السبت|' +
'الأحد')
}
},
get regionDateLabel() {
return this.findElement('languageRegionDateLabel').text();
},
get currentLanguageFromMozSettings() {
return this.client.settings.get('language.current');
},
get currentLanguageLabel() {
return this.findElement('languageLabel').text();
},
get currentLanguage() {
var languageLabel = this.currentLanguageLabel;
var realLanguage;
for (var languageKey in this._languageMap) {
if (this._languageMap[languageKey].label === languageLabel) {
realLanguage = languageKey;
break;
}
}
return realLanguage;
},
set currentLanguage(value) {
if (this._languageMap[value]) {
var oldLanguage = this.currentLanguage;
this.tapSelectOption('languageChangeSelect',
this._languageMap[value].desc);
this.client.waitFor(function() {
var newLanguage = this.currentLanguage;
return oldLanguage !== newLanguage;
}.bind(this));
}
},
setupDefaultLanguage: function() {
if (this.currentLanguage !== 'english') {
this.currentLanguage = 'english';
}
},
isSampleFormatTranslated: function(languageKey) {
if (this._languageMap[languageKey]) {
var rule = this._languageMap[languageKey].dayRules;
if (this.regionDateLabel.match(rule)) {
return true;
}
}
return false;
},
back: function() {
var parentSection = this.waitForElement('languagePanel');
var bodyWidth = this.findElement('body').size().width;
this.client.switchToShadowRoot(this.findElement('header'));
this.client.findElement('[action="back"] button').tap();
this.client.switchToShadowRoot();
this.client.waitFor(function() {
var loc = parentSection.location();
return Math.abs(loc.x) >= bodyWidth;
});
}
};

View file

@ -0,0 +1,73 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings media storage panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function MediaStoragePanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, MediaStoragePanel.Selectors);
}
function hasNumbers(t) {
return /\d/.test(t);
}
module.exports = MediaStoragePanel;
MediaStoragePanel.Selectors = {
'formatSdcardButton':
'#mediaStorage button[data-l10n-id="format-sdcard-external-0"]',
'formatSdcardDialog': '#format-sdcard-dialog',
'mediaLocationSelector':
'#mediaStorage select[name="device.storage.writable.name"]',
'musicSpace': 'a[data-l10n-id="music-space"]>span',
'pictureSpace': 'a[data-l10n-id="pictures-space"]>span',
'videoSpace': 'a[data-l10n-id="videos-space"]>span',
'mediaFreeSpace': 'a[data-l10n-id="free-space"]>span',
'mediaTotalSpace': 'a[data-l10n-id="total-space"]>span'
};
MediaStoragePanel.prototype = {
__proto__: Base.prototype,
tapOnFormatSdcardButton: function() {
this.waitForElement('formatSdcardButton').tap();
},
get isFormatSdcardDialogShowed() {
return this.findElement('formatSdcardDialog')
.getAttribute('hidden');
},
get isMediaLocationSelectorEnabled() {
return !this.findElement('mediaLocationSelector')
.getAttribute('disabled');
},
get containNumberInMusicSpace() {
return hasNumbers(this.waitForElement('musicSpace').text());
},
get containNumberInPictureSpace() {
return hasNumbers(this.waitForElement('pictureSpace').text());
},
get containNumberInVideoSpace() {
return hasNumbers(this.waitForElement('videoSpace').text());
},
get containNumberInFreeSpace() {
return hasNumbers(this.waitForElement('mediaFreeSpace').text());
},
get containNumberInTotalSpace() {
return hasNumbers(this.waitForElement('mediaTotalSpace').text());
}
};

View file

@ -0,0 +1,166 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings do not track panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function MessagePanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, MessagePanel.Selectors);
}
module.exports = MessagePanel;
MessagePanel.Selectors = {
'deliveryReportMenuItem': '#menuItem-deliveryReport span',
'deliveryReportCheckbox': '#menuItem-deliveryReport input[type="checkbox"]',
'readReportMenuItem': '#menuItem-readReport span',
'readReportCheckbox': '#menuItem-readReport input[type="checkbox"]',
'wapPushMenuItem': '#menuItem-wapPush',
'wapPushCheckbox': '#menuItem-wapPush input[type="checkbox"]',
'cellBroadcastMenuItem': '#menuItem-cellBroadcast',
'cellBroadcastCheckbox': '#menuItem-cellBroadcast gaia-checkbox',
'emergencyAlertMenuItem': '#menuItem-emergencyAlert',
'emergencyAlertCheckbox': '#menuItem-emergencyAlert gaia-checkbox',
'retrieveSelect': 'select[name="ril.mms.retrieval_mode"]',
'messageContentDiv': '#messaging > div'
};
MessagePanel.prototype = {
__proto__: Base.prototype,
settingsKeys: [
'ril.sms.requestStatusReport.enabled',
'ril.mms.requestReadReport.enabled',
'wap.push.enabled',
'ril.cellbroadcast.disabled',
'cmas.enabled'
],
checkboxes: [
'deliveryReportCheckbox',
'readReportCheckbox',
'wapPushCheckbox',
'cellBroadcastCheckbox',
'emergencyAlertCheckbox'
],
menuItems: [
'deliveryReportMenuItem',
'readReportMenuItem',
'wapPushMenuItem',
'cellBroadcastMenuItem',
'emergencyAlertMenuItem'
],
get deliveryReportMenuItem() {
return this.findElement('deliveryReportMenuItem');
},
get deliveryReportCheckbox() {
return this.findElement('deliveryReportCheckbox');
},
get readReportMenuItem() {
return this.findElement('readReportMenuItem');
},
get readReportCheckbox() {
return this.findElement('readReportCheckbox');
},
get wapPushMenuItem() {
return this.findElement('wapPushMenuItem');
},
get wapPushCheckbox() {
return this.findElement('wapPushCheckbox');
},
get cellBroadcastMenuItem() {
return this.findElement('cellBroadcastMenuItem');
},
get cellBroadcastCheckbox() {
return this.findElement('cellBroadcastCheckbox');
},
get emergencyAlertMenuItem() {
return this.findElement('emergencyAlertMenuItem');
},
get emergencyAlertCheckbox() {
return this.findElement('emergencyAlertCheckbox');
},
get isEmergencyAlertCheckboxEnabled() {
return !this.findElement('emergencyAlertCheckbox')
.getAttribute('disabled');
},
get messageContentDiv() {
return this.findElement('messageContentDiv');
},
chooseRetrieveMethod: function(optionText) {
this.tapSelectOption('retrieveSelect', optionText);
},
getSelectedRetrieveMethod: function() {
return this.client.settings.get('ril.mms.retrieval_mode');
},
initialMessagingSettings: function() {
this._resetCheckboxes();
this._resetSelect();
this._scrollMessageContentToTop();
},
toggleMenuItem: function(menuItemName, value) {
var checked = !!this[menuItemName + 'Checkbox'].getAttribute('checked');
if (checked !== value) {
this[menuItemName + 'MenuItem'].tap();
}
},
isChecked: function(elementName) {
return !!this.findElement(elementName).getAttribute('checked');
},
/**
* Returns the checked status of a web component.
* We need to execute script because the custom attribute does not
* work in marionette.
*/
isComponentChecked: function(elementName) {
return !!this.findElement(elementName).scriptWith(function(el) {
return el.wrappedJSObject.checked;
});
},
_resetSelect: function() {
this.chooseRetrieveMethod('Off');
},
_resetCheckboxes: function() {
var self = this;
this._scrollMessageContentToTop();
this.checkboxes.forEach(function(checkbox, index) {
var checked = !!self[checkbox].getAttribute('checked');
if (checked) {
var menuItemKey = self.menuItems[index];
self[menuItemKey].tap();
}
});
},
_scrollMessageContentToTop: function() {
// it seems that the screen will scroll to bottom sometimes
this.messageContentDiv.scriptWith(function(el) {
el.scrollTop = 0;
});
}
};

View file

@ -0,0 +1,36 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings notification panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function NotificationsPanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, NotificationsPanel.Selectors);
}
module.exports = NotificationsPanel;
NotificationsPanel.Selectors = {
'showOnLockScreenCheckbox': '#notifications gaia-switch'
};
NotificationsPanel.prototype = {
__proto__: Base.prototype,
get isShowOnLockScreenEnabled() {
return this.findElement('showOnLockScreenCheckbox')
.getAttribute('checked') &&
this.client.settings.get('lockscreen.notifications-preview.enabled');
},
tapOnShowOnLockScreen: function() {
this.waitForElement('showOnLockScreenCheckbox').click();
}
};

View file

@ -0,0 +1,174 @@
'use strict';
var Base = require('../base');
var LanguagePanel = require('./language');
/**
* Abstraction around settings root panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function RootPanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, RootPanel.Selectors);
}
module.exports = RootPanel;
RootPanel.Selectors = {
'airplaneModeCheckbox': '.airplaneMode-input',
'airplaneModeMenuItem': '#menuItem-airplaneMode',
'applicationStorageDesc': '.application-storage-desc',
'batteryDesc': '.battery-desc',
'bluetoothDesc': '.bluetooth-desc',
'firefoxAccountDesc': '#fxa-desc',
'geolocationCheckbox': 'gaia-switch[name="geolocation.enabled"]',
'languageDesc': '.language-desc',
'mediaStorageDesc': '.media-storage-desc',
'simManagerItem': '#simCardManager-settings',
'simSecurityItem': '#simSecurity-settings',
'screenLockDesc': '.screenLock-desc',
'wifiDesc': '#wifi-desc',
'nfcCheckbox': '#nfc-input'
};
RootPanel.prototype = {
__proto__: Base.prototype,
// application storage
get applicationStorageDesc() {
return this.waitForElement('applicationStorageDesc').text();
},
// airplane mode
airplaneMode: function(enabled) {
var self = this;
this.client.waitFor(function() {
return self.airplaneModeCheckboxEnabled;
});
if (enabled !== this.airplaneModeCheckboxChecked) {
this.waitForElement('airplaneModeCheckbox').click();
this.client.waitFor(function() {
return enabled === self.airplaneModeCheckboxChecked;
});
}
// make sure we would wait for two more status here
if (enabled === true) {
this.client.waitFor(function() {
return self.WiFiDesc === 'Disabled';
});
this.client.waitFor(function() {
return self.bluetoothDesc === 'Turned off';
});
}
},
get airplaneModeCheckboxChecked() {
return !!this.findElement('airplaneModeCheckbox').scriptWith(function(el) {
return el.wrappedJSObject.checked;
});
},
get airplaneModeCheckboxEnabled() {
return this.findElement('airplaneModeCheckbox').scriptWith(function(el) {
return !el.wrappedJSObject.hasAttribute('disabled');
});
},
// battery
get batteryDesc() {
return this.waitForElement('batteryDesc').text();
},
// bluetooth
get bluetoothDesc() {
return this.waitForElement('bluetoothDesc').text();
},
// firefox account
get firefoxAccountDesc() {
return this.waitForElement('firefoxAccountDesc').text();
},
// geolocation
geolocation: function(enabled) {
if (enabled !== this.geolocationCheckboxChecked) {
this.waitForElement('geolocationCheckbox').tap();
this.client.waitFor(function() {
return enabled === this.geolocationCheckboxChecked;
}.bind(this));
}
},
get geolocationCheckboxChecked() {
return !!this.findElement('geolocationCheckbox').scriptWith(function(el) {
return el.wrappedJSObject.checked;
});
},
get geolocationEnabledSetting() {
return this.client.settings.get('geolocation.enabled');
},
get wifiEnabledSetting() {
return this.client.settings.get('wifi.enabled');
},
get bluetoothEnabledSetting() {
return this.client.settings.get('bluetooth.enabled');
},
get nfcCheckboxChecked() {
return !!this.findElement('nfcCheckbox').scriptWith(function(el) {
return el.wrappedJSObject.checked;
});
},
// language
isLanguageDescTranslated: function(languageKey) {
if (!LanguagePanel.prototype._languageMap[languageKey]) {
return false;
}
var expected;
this.client.waitFor(function() {
expected = LanguagePanel.prototype._languageMap[languageKey].desc;
return this.languageDesc === expected;
}.bind(this));
return true;
},
get languageDesc() {
return this.findElement('languageDesc').text();
},
// media storage
get mediaStorageDesc() {
return this.waitForElement('mediaStorageDesc').text();
},
// screen lock
get screenLockDesc() {
return this.waitForElement('screenLockDesc').text();
},
// wifi
get WiFiDesc() {
return this.waitForElement('wifiDesc').text();
},
// sim manager
get isSimManagerItemVisible() {
return this.findElement('simManagerItem').displayed();
},
get isSimSecurityItemVisible() {
return this.findElement('simSecurityItem').displayed();
}
};

View file

@ -0,0 +1,150 @@
/* global require, module */
'use strict';
var Base = require('../base');
/**
* Abstraction around settings screenLock panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function ScreenLockPanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, ScreenLockPanel.Selectors);
}
module.exports = ScreenLockPanel;
ScreenLockPanel.Selectors = {
'screenLockLabel': 'label[data-l10n-id="lockScreen"]',
'screenLockCheckbox': '.lockscreen-enable',
'header': 'gaia-header',
'passcodeLockLabel': 'label[data-l10n-id="passcode-lock"]',
'passcodeInput': '.passcode-input',
'passcodeCheckbox': '.passcode-enable',
'passcodeIsNotMatchedLabel': 'div[data-l10n-id="passcode-doesnt-match"]',
'passcodeIncorrectLabel': 'div[data-l10n-id="incorrect-passcode"]',
'passcodeCreateButton': 'button[type="submit"]',
'passcodeEditButton': '.passcode-edit',
'passcodeChangeButton': 'button[type="submit"]',
'passcodePanel': '#screenLock-passcode',
'screenLockHeaderLabel': 'h1[data-l10n-id="screenLock-header"]'
};
ScreenLockPanel.prototype = {
__proto__: Base.prototype,
isScreenLockEnabled: function() {
return this.client.settings.get('lockscreen.enabled');
},
isScreenLockChecked: function() {
return !!this.findElement('screenLockCheckbox').scriptWith(function(el) {
return el.wrappedJSObject.checked;
});
},
isPasscodeLockEnabled: function() {
return this.client.settings.get('lockscreen.passcode-lock.enabled');
},
isPasscodeChecked: function() {
return !!this.findElement('passcodeCheckbox').scriptWith(function(el) {
return el.wrappedJSObject.checked;
});
},
isPasscodeNotMatched: function() {
return this.findElement('passcodeIsNotMatchedLabel').displayed();
},
isPasscodeIncorrect: function() {
return this.findElement('passcodeIncorrectLabel').displayed();
},
isPasscodePanelVisible: function() {
return this.findElement('passcodePanel').displayed();
},
isScreenLockHeaderLabelVisible: function() {
return this.findElement('screenLockHeaderLabel').displayed();
},
enableScreenLock: function() {
this.waitForElement('screenLockLabel').tap();
this.client.waitFor(function() {
return this.isScreenLockEnabled();
}.bind(this));
},
setupScreenLock: function() {
// make sure we are at the root panel at first
if (this.isPasscodePanelVisible()) {
this.tapBackButton();
}
// we have to make sure screenLock is disabled by default
if (!this.isScreenLockEnabled()) {
return;
}
// if we have passcode by default, then there is a popup
// when disabling screenLock, in this way, we have to
// type the correct code to disable passcodeLock at first
if (this.isPasscodeLockEnabled()) {
var code = this.getPasscode();
this.togglePasscodeLock();
this.typePasscode(code);
}
// then we can disable screenLock
this.toggleScreenLock();
},
toggleScreenLock: function() {
this.waitForElement('screenLockLabel').tap();
},
togglePasscodeLock: function() {
this.waitForElement('passcodeLockLabel').tap();
},
_typePasscode: function(keys) {
this.waitForElement('passcodeInput').sendKeys(keys);
},
typePasscode: function(key1, key2) {
if (key1) {
this._typePasscode(key1);
if (key2) {
this._typePasscode(key2);
}
}
},
tapBackButton: function() {
this.waitForElement('header').tap(25, 25);
},
tapCreatePasscode: function() {
this.waitForElement('passcodeCreateButton').tap();
// we have to make sure transition is done
this.client.waitFor(function() {
return this.isScreenLockHeaderLabelVisible();
}.bind(this));
},
tapEditPasscode: function(keys) {
this.waitForElement('passcodeEditButton').tap();
if (keys) {
this._typePasscode(keys);
}
},
tapChangePasscode: function() {
this.waitForElement('passcodeChangeButton').tap();
}
};

View file

@ -0,0 +1,145 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings sound panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function SoundPanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, SoundPanel.Selectors);
}
module.exports = SoundPanel;
SoundPanel.Selectors = {
'vibrateCheckbox': '#sound gaia-switch[name="vibration.enabled"]',
'mediaSlider': '#sound .media input',
'ringerSlider': '#sound .notification input',
'alarmSlider': '#sound .alarm input',
'keypadCheckbox': '#sound [name="phone.ring.keypad"]',
'cameraCheckbox': '#sound [name="camera.sound.enabled"]',
'sentMessageCheckbox':
'#sound [name="message.sent-sound.enabled"]',
'unlockScreenCheckbox':
'#sound [name="lockscreen.unlock-sound.enabled"]',
'alerttoneButton': '.alert-tone-selection',
'alerttoneButtonDesc': '.alert-tone-selection .desc',
'ringtoneButton': '.ring-tone-selection',
'ringtoneButtonDesc': '.ring-tone-selection .desc',
'manageTonesButton': '.manage-tones-button'
};
SoundPanel.prototype = {
__proto__: Base.prototype,
isGaiaCheckboxChecked: function(selector) {
return this.findElement(selector).scriptWith(function(el) {
return el.wrappedJSObject.checked;
});
},
get isVibrateEnabled() {
return this.findElement('vibrateCheckbox')
.getAttribute('checked') &&
this.client.settings.get('vibration.enabled');
},
tapOnVibration: function() {
this.waitForElement('vibrateCheckbox').tap();
},
/* Volume */
get contentValue() {
return this.client.settings.get('audio.volume.content');
},
tapOnMediaSlider: function() {
this.waitForElement('mediaSlider').tap();
},
get ringerValue() {
return this.client.settings.get('audio.volume.notification');
},
tapOnRingerSlider: function() {
this.waitForElement('ringerSlider').tap();
},
get alarmValue() {
return this.client.settings.get('audio.volume.alarm');
},
tapOnAlarmSlider: function() {
this.waitForElement('alarmSlider').tap();
},
/* Other sounds */
get isKeypadChecked() {
return this.isGaiaCheckboxChecked('keypadCheckbox') &&
this.client.settings.get('phone.ring.keypad');
},
tapOnKeypad: function() {
this.waitForElement('keypadCheckbox').tap();
},
get isCameraChecked() {
return this.isGaiaCheckboxChecked('cameraCheckbox') &&
this.client.settings.get('camera.sound.enabled');
},
tapOnCamera: function() {
this.waitForElement('cameraCheckbox').tap();
},
get isSentMessageChecked() {
return this.isGaiaCheckboxChecked('sentMessageCheckbox') &&
this.client.settings.get('message.sent-sound.enabled');
},
tapOnSentMessage: function() {
this.waitForElement('sentMessageCheckbox').tap();
},
get isUnlockScreenChecked() {
return this.isGaiaCheckboxChecked('unlockScreenCheckbox') &&
this.client.settings.get('message.sent-sound.enabled');
},
tapOnUnlockScreen: function() {
this.waitForElement('unlockScreenCheckbox').tap();
},
clickRingToneSelect: function() {
this.waitForElement('ringtoneButton').tap();
},
clickAlertToneSelect: function() {
this.waitForElement('alerttoneButton').tap();
},
clickManageTones: function() {
this.waitForElement('manageTonesButton').tap();
},
get selectedRingtone() {
return this.waitForElement('ringtoneButtonDesc').text();
},
get selectedAlertTone() {
return this.waitForElement('alerttoneButtonDesc').text();
},
getSelectedTone: function(type) {
if (type === 'ringtone') {
return this.selectedRingtone;
} else if (type === 'alerttone') {
return this.selectedAlertTone;
}
}
};

View file

@ -0,0 +1,50 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings support panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function SupportPanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, SupportPanel.Selectors);
}
module.exports = SupportPanel;
SupportPanel.Selectors = {
'onlineSupport': '#online-support-text [href]',
'callSupports': '#call-support-numbers [href]'
};
SupportPanel.prototype = {
__proto__: Base.prototype,
get isOnlineSupportEnabled() {
var retval = false;
try {
this.onlineSupport;
retval = true;
} catch (ex) {
retval = false;
}
return retval;
},
get isCallSupportEnabled() {
return this.callSupports.length > 0;
},
get onlineSupport() {
return this.findElement('onlineSupport');
},
get callSupports() {
return this.findElements('callSupports');
}
};

View file

@ -0,0 +1,42 @@
'use strict';
var Base = require('../base');
/**
* Abstraction around settings bluetooth panel
* @constructor
* @param {Marionette.Client} client for operations.
*/
function UsbStoragePanel(client) {
// Call the Base constructor to initiate base class.
Base.call(this, client, null, UsbStoragePanel.Selectors);
}
module.exports = UsbStoragePanel;
UsbStoragePanel.Selectors = {
'usbEnabledCheckbox': '.ums-switch',
'confirmButton': '#settings-confirm-dialog button[type="submit"]'
};
UsbStoragePanel.prototype = {
__proto__: Base.prototype,
get isUsbEnabledSwitchChecked() {
// Marionette has trouble returning custom properties on shadow roots.
// For now query the shadowRoot for checked status.
return this.findElement('usbEnabledCheckbox')
.scriptWith(function(el) {
return el.shadowRoot.querySelector('input[type="checkbox"]').checked;
});
},
get isUmsEnabled() {
return this.client.settings.get('ums.enabled');
},
tapUsbEnabledSwitch: function() {
this.waitForElement('usbEnabledCheckbox').tap();
}
};

View file

@ -0,0 +1,57 @@
'use strict';
var Base = require('./base');
// origin of the settings app
var ORIGIN = 'app://settings.gaiamobile.org';
/**
* Abstraction around system app
* @constructor
* @param {Marionette.Client} client for operations.
*/
function SystemApp(client) {
Base.call(this, client, ORIGIN, SystemApp.Selectors);
}
module.exports = SystemApp;
SystemApp.Selectors = {
'actionMenu': 'form[data-z-index-level="action-menu"]',
'valueSelector': '.value-selector',
'confirmOkButton': '.appWindow.active .modal-dialog-confirm-ok'
};
SystemApp.prototype = {
__proto__: Base.prototype,
isActionMenuVisible: function() {
var actionMenu = null,
displayed = false;
this.client.switchToFrame();
actionMenu = this.waitForElement('actionMenu');
displayed = actionMenu && actionMenu.displayed();
// Go back to settings app.
this.launch();
return displayed;
},
isValueSelectorVisible: function() {
var valueSelector = null,
displayed = false;
this.client.switchToFrame();
valueSelector = this.waitForElement('valueSelector');
displayed = valueSelector && valueSelector.displayed();
// Go back to settings app.
this.launch();
return displayed;
},
/*
/* Click the ok button on window.confirm dialog.
*/
confirmOk: function() {
this.client.switchToFrame();
var confirmButton = this.waitForElement('confirmOkButton');
confirmButton.click();
}
};

View file

@ -0,0 +1,33 @@
/*global Components, Services */
'use strict';
var Cu = Components.utils;
Cu.import('resource://gre/modules/Services.jsm');
Services.obs.addObserver(function(document) {
if (!document || !document.location) {
return;
}
var window = document.defaultView;
var _bluetooth = {
isConnected: function() { return false; },
getDefaultAdapter: function() { return new window.Object(); },
addEventListener: function() {},
enabled: false,
onenabled: null,
ondisabled: null,
onadapteradded: null
};
Object.defineProperty(window.wrappedJSObject.navigator, 'mozBluetooth', {
configurable: false,
writable: false,
value: Cu.cloneInto(
_bluetooth,
window,
{cloneFunctions: true}
)
});
}, 'document-element-inserted', false);

View file

@ -0,0 +1,21 @@
/*global Components, Services */
'use strict';
Components.utils.import('resource://gre/modules/Services.jsm');
Services.obs.addObserver(function(document) {
if (!document || !document.location) {
return;
}
var window = document.defaultView.wrappedJSObject;
var _mobileConnections = new document.defaultView.Array({});
Object.defineProperty(window.navigator, 'mozMobileConnections', {
configurable: false,
get: function() {
return _mobileConnections;
}
});
}, 'document-element-inserted', false);

View file

@ -0,0 +1,21 @@
/*global Components, Services */
'use strict';
Components.utils.import('resource://gre/modules/Services.jsm');
Services.obs.addObserver(function(document) {
if (!document || !document.location) {
return;
}
var window = document.defaultView.wrappedJSObject;
var _mobileConnections = new document.defaultView.Array({}, {});
Object.defineProperty(window.navigator, 'mozMobileConnections', {
configurable: false,
get: function() {
return _mobileConnections;
}
});
}, 'document-element-inserted', false);

View file

@ -0,0 +1,19 @@
/*global Components, Services */
'use strict';
Components.utils.import('resource://gre/modules/Services.jsm');
Services.obs.addObserver(function(document) {
if (!document || !document.location) {
return;
}
var window = document.defaultView.wrappedJSObject;
Object.defineProperty(window.navigator, 'mozTelephony', {
configurable: false,
get: function() {
return {};
}
});
}, 'document-element-inserted', false);

View file

@ -0,0 +1,23 @@
/*global Components, Services */
'use strict';
var Cu = Components.utils;
Cu.import('resource://gre/modules/Services.jsm');
Services.obs.addObserver(function(document) {
if (!document || !document.location) {
return;
}
var window = document.defaultView;
Object.defineProperty(window.wrappedJSObject.navigator, 'mozWifiManager', {
configurable: false,
writable: false,
value: Cu.cloneInto(
{enabled: false},
window,
{cloneFunctions: true}
)
});
}, 'document-element-inserted', false);

View file

@ -0,0 +1,57 @@
'use strict';
var Settings = require('../app/app'),
assert = require('assert');
// Note :
// This test is only run on devices
marionette('airplaneMode settings', function() {
var client = marionette.client({
desiredCapabilities: { raisesAccessibilityExceptions: false }
});
var settingsApp;
var rootPanel;
setup(function() {
settingsApp = new Settings(client);
settingsApp.launch();
rootPanel = settingsApp.rootPanel;
});
suite('Turning airplaneMode from off to on', function() {
setup(function() {
prepareDefaultServices();
rootPanel.airplaneMode(false);
});
test('all related services will be turned off', function() {
rootPanel.airplaneMode(true);
assert.equal(rootPanel.wifiEnabledSetting, false);
assert.equal(rootPanel.bluetoothEnabledSetting, false);
assert.equal(rootPanel.geolocationCheckboxChecked, false);
assert.equal(rootPanel.nfcCheckboxChecked, false);
});
});
suite('Turning airplaneMode from on to off', function() {
setup(function() {
prepareDefaultServices();
rootPanel.airplaneMode(true);
});
test('all related services will be turned on', function() {
rootPanel.airplaneMode(false);
assert.equal(rootPanel.wifiEnabledSetting, true);
assert.equal(rootPanel.bluetoothEnabledSetting, true);
assert.equal(rootPanel.geolocationCheckboxChecked, true);
assert.equal(rootPanel.nfcCheckboxChecked, true);
});
});
function prepareDefaultServices() {
client.settings.set('airplaneMode.enabled', false);
client.settings.set('wifi.enabled', true);
client.settings.set('bluetooth.enabled', true);
client.settings.set('geolocation.enabled', true);
client.settings.set('nfc.enabled', true);
}
});

View file

@ -0,0 +1,23 @@
'use strict';
var Settings = require('../app/app'),
assert = require('assert');
marionette('manipulate app permissions', function() {
var client = marionette.client({
desiredCapabilities: { raisesAccessibilityExceptions: false }
});
var settingsApp;
var appPermissionPanel;
setup(function() {
settingsApp = new Settings(client);
settingsApp.launch();
appPermissionPanel = settingsApp.appPermissionPanel;
});
test('set geolocation of first app to Grant', function() {
appPermissionPanel.enterPermissionDetail();
appPermissionPanel.tapGeolocationSelect('Grant');
assert.equal(appPermissionPanel.georlocationSelectValue, 'allow');
});
});

View file

@ -0,0 +1,28 @@
'use strict';
var Settings = require('../app/app'),
assert = require('assert');
marionette('manipulate app storage settings', function() {
var client = marionette.client();
var settingsApp;
var appStoragePanel;
function gotoAppStoragePanel() {
settingsApp = new Settings(client);
settingsApp.launch();
// Navigate to the Support menu
appStoragePanel = settingsApp.appStoragePanel;
}
suite('check app storage basics', function() {
setup(function() {
gotoAppStoragePanel();
});
test('check storage data contain numbers', function() {
assert.ok(appStoragePanel.containNumberInAppTotalSpace);
assert.ok(appStoragePanel.containNumberInAppUsedSpace);
assert.ok(appStoragePanel.containNumberInAppFreeSpace);
});
});
});

View file

@ -0,0 +1,42 @@
'use strict';
var Settings = require('../app/app'),
assert = require('assert');
marionette('manipulate battery settings', function() {
var client = marionette.client({
desiredCapabilities: { raisesAccessibilityExceptions: false }
});
var settingsApp;
var batteryPanel;
setup(function() {
settingsApp = new Settings(client);
settingsApp.launch();
// Navigate to the battery menu
batteryPanel = settingsApp.batteryPanel;
});
test('check power save mode initial state', function() {
assert.ok(
!batteryPanel.isPowerSavingEnabled,
'power save mode is disabled by default'
);
});
test('enable power save mode', function() {
batteryPanel.enablePowerSaveMode();
assert.ok(
batteryPanel.isPowerSavingEnabled,
'power save mode has been enabled'
);
});
test('open Turn On Period option selector', function() {
batteryPanel.changeTurnOnPeriod();
assert.ok(
batteryPanel.isLastOptionSelected,
'Turn On Period option can be tapped'
);
});
});

View file

@ -0,0 +1,34 @@
'use strict';
var Settings = require('../app/app'),
assert = require('assert');
marionette('manipulate bluetooth settings', function() {
var client = marionette.client({
desiredCapabilities: { raisesAccessibilityExceptions: false }
});
var settingsApp;
var bluetoothPanel;
setup(function() {
settingsApp = new Settings(client);
settingsApp.launch();
// Navigate to the Bluetooth menu
bluetoothPanel = settingsApp.bluetoothPanel;
});
test('check bluetooth initial state', function() {
assert.ok(
!bluetoothPanel.isBluetoothEnabled,
'bluetooth is disabled by default'
);
});
test('enable bluetooth', function() {
bluetoothPanel.enableBluetooth();
assert.ok(
bluetoothPanel.isBluetoothEnabled,
'bluetooth has been enabled'
);
});
});

View file

@ -0,0 +1,91 @@
'use strict';
var Settings = require('../app/app'),
assert = require('assert');
marionette('manipulate browsing privacy settings', function() {
var client = marionette.client({
desiredCapabilities: { raisesAccessibilityExceptions: false }
});
var settingsApp;
var browsingPrivacyPanel;
setup(function() {
settingsApp = new Settings(client);
settingsApp.launch();
// Navigate to the Browsing Privacy menu
browsingPrivacyPanel = settingsApp.browsingPrivacyPanel;
});
test('check private browsing initial state and toggle', function() {
assert.ok(
!browsingPrivacyPanel.isPrivateBrowsingEnabled,
'private browsing disabled by default'
);
browsingPrivacyPanel.enablePrivateBrowsing();
assert.ok(
browsingPrivacyPanel.isPrivateBrowsingEnabled,
'private browsing has been enabled'
);
});
test('check tracking protection initial state and toggle', function() {
assert.ok(
!browsingPrivacyPanel.isTrackingProtectionEnabled,
'tracking protection disabled by default'
);
browsingPrivacyPanel.enableTrackingProtection();
assert.ok(
browsingPrivacyPanel.isTrackingProtectionEnabled,
'tracking protection has been enabled'
);
});
test('check clear history button, confirm dialog will show' +
'click cancel, and click submit', function() {
browsingPrivacyPanel.clickClearHistoryButton();
assert.ok(
browsingPrivacyPanel.confirmDialogShown,
'confirm dialog is shown'
);
browsingPrivacyPanel.clickConfirmDialogCancel();
assert.ok(
!browsingPrivacyPanel.confirmDialogShown,
'confirm dialog is hidden'
);
browsingPrivacyPanel.clickClearHistoryButton();
assert.ok(
browsingPrivacyPanel.confirmDialogShown,
'confirm dialog is shown'
);
browsingPrivacyPanel.clickConfirmDialogSubmit();
assert.ok(
!browsingPrivacyPanel.confirmDialogShown,
'confirm dialog is hidden'
);
});
test('check private data button, confirm dialog will show' +
'click cancel, and click submit', function() {
browsingPrivacyPanel.clickClearPrivateDataButton();
assert.ok(
browsingPrivacyPanel.confirmDialogShown,
'confirm dialog is shown'
);
browsingPrivacyPanel.clickConfirmDialogCancel();
assert.ok(
!browsingPrivacyPanel.confirmDialogShown,
'confirm dialog is hidden'
);
browsingPrivacyPanel.clickClearPrivateDataButton();
assert.ok(
browsingPrivacyPanel.confirmDialogShown,
'confirm dialog is shown'
);
browsingPrivacyPanel.clickConfirmDialogSubmit();
assert.ok(
!browsingPrivacyPanel.confirmDialogShown,
'confirm dialog is hidden'
);
});
});

View file

@ -0,0 +1,21 @@
'use strict';
var Settings = require('../app/app');
marionette('manipulate date time settings', function() {
var client = marionette.client();
var settingsApp;
var dateTimePanel;
setup(function() {
settingsApp = new Settings(client);
settingsApp.launch();
dateTimePanel = settingsApp.dateTimePanel;
});
test('manipulate time format', function() {
// Simply select the value in the time format to
// ensure the menu is is populated.
dateTimePanel.selectTimeFormat('12-hour');
});
});

View file

@ -0,0 +1,60 @@
'use strict';
var Settings = require('../app/app'),
assert = require('assert');
marionette('check device information settings', function() {
var client = marionette.client({
profile: {
settings: {
'developer.menu.enabled': false
}
},
desiredCapabilities: { raisesAccessibilityExceptions: false }
});
var settingsApp;
var deviceInfoPanel, developerPanel;
setup(function() {
settingsApp = new Settings(client);
settingsApp.launch();
deviceInfoPanel = settingsApp.aboutPanel;
});
test('check more info panel', function() {
deviceInfoPanel.tapOnMoreInfoButton();
assert.equal(false, deviceInfoPanel.isDevelopMenuEnabled);
deviceInfoPanel.triggerDevelopMenu();
assert.equal(true, deviceInfoPanel.isDevelopMenuEnabled);
deviceInfoPanel.tapMoreInfoBackBtn();
deviceInfoPanel.tapDeviceInfoBackBtn();
assert.equal(true, deviceInfoPanel.isDeveloperMenuItemVisible);
developerPanel = settingsApp.developerPanel;
});
test('check your rights panel', function() {
deviceInfoPanel.tapOnYourRightsButton();
});
test('check your privacy panel', function() {
deviceInfoPanel.tapOnYourPrivacyButton();
deviceInfoPanel.tapOnPrivacyBrowserButton();
});
test('check legal information panel', function() {
deviceInfoPanel.tapOnLegalInfoButton();
deviceInfoPanel.tapOnOpenSourceNoticesButton();
deviceInfoPanel.tapOpenSourceNoticesBackBtn();
deviceInfoPanel.tapOnObtainingSourceCodeButton();
});
test('check reset phone', function() {
assert.ok(!deviceInfoPanel.isResetPhoneDialogVisible,
'Reset phone dialog is hidden');
deviceInfoPanel.tapOnResetPhoneButton();
assert.ok(deviceInfoPanel.isResetPhoneDialogVisible,
'Reset phone dialog is visible');
deviceInfoPanel.tapOnCancelResetPhoneButton();
assert.ok(!deviceInfoPanel.isResetPhoneDialogVisible,
'Reset phone dialog is hidden');
});
});

View file

@ -0,0 +1,143 @@
'use strict';
var Settings = require('../app/app'),
SystemApp = require('../app/system_app'),
assert = require('assert');
marionette('manipulate display settings', function() {
var client = marionette.client({
desiredCapabilities: { raisesAccessibilityExceptions: false }
});
var settingsApp;
var systemApp;
var displayPanel;
setup(function() {
systemApp = new SystemApp(client);
settingsApp = new Settings(client);
settingsApp.launch();
});
suite('check visibility of auto-brightness-toggle', function() {
test('show the toggle when with light sensor', function() {
client.executeScript(function() {
var theWindow = window.wrappedJSObject;
theWindow.LazyLoader.getJSON = function(path) {
return Promise.resolve({ ambientLight: true });
};
});
// Navigate to the display menu
// We need to mock LazyLoader.getJSON function before switching to panel.
displayPanel = settingsApp.displayPanel;
assert.ok(displayPanel.isAutoBrightnessItemVisible);
});
test('hide the toggle when without light sensor', function() {
client.executeScript(function() {
var theWindow = window.wrappedJSObject;
theWindow.LazyLoader.getJSON = function(path) {
return Promise.resolve({ ambientLight: false });
};
});
// Navigate to the display menu
displayPanel = settingsApp.displayPanel;
assert.ok(!displayPanel.isAutoBrightnessItemVisible);
});
});
suite('adjust brightness automatically', function() {
setup(function() {
// Navigate to the display menu
displayPanel = settingsApp.displayPanel;
});
suite('lock orientation', function() {
test('check default value', function() {
assert.ok(
!displayPanel.isLockOrientationChecked,
'lock orientation is disabled by default'
);
});
test('tap toggle', function() {
displayPanel.tapLockOrientationCheckbox();
client.waitFor(function() {
return displayPanel.isLockOrientationChecked;
}.bind(this));
assert.ok(
displayPanel.isLockOrientationChecked,
'lock orientation is enabled'
);
assert.ok(
displayPanel.screenOrientationSetting,
'screen.orientation.lock is true'
);
});
});
suite('check brightness functionality', function() {
var defaultAutoBrightnessEnabled;
test('check default value', function() {
// get the auto brightness value from mozSettings
defaultAutoBrightnessEnabled =
displayPanel.autoBrightnessSetting || false;
assert.ok(
displayPanel.isAutoBrightnessChecked === defaultAutoBrightnessEnabled,
'default adjust automatically enabled: ' +
defaultAutoBrightnessEnabled
);
});
test('tap toggle', function() {
displayPanel.tapAutoBrightnessCheckbox();
client.waitFor(function() {
return displayPanel.isAutoBrightnessChecked;
}.bind(this));
assert.ok(
displayPanel.isAutoBrightnessChecked !== defaultAutoBrightnessEnabled,
'adjust automatically enabled: ' + !defaultAutoBrightnessEnabled
);
assert.ok(displayPanel.autoBrightnessSetting !==
defaultAutoBrightnessEnabled);
var expectedVisibility = !displayPanel.isAutoBrightnessChecked;
assert.ok(
displayPanel.isBrightnessManualItemVisible === expectedVisibility,
'manual brightness item visibility: ' + expectedVisibility
);
});
});
suite('screen timeout', function() {
// Skip the test as currently we are not able to tap on a select element.
// Please refer to bug 977522 for details.
test.skip('tap selector', function() {
displayPanel.tapScreenTimeoutSelector();
assert.ok(
systemApp.isValueSelectorVisible(),
'screen timeout selector shows up'
);
});
test('tap screen timeout option', function() {
displayPanel.tapScreenTimeoutSelectOption('1 minute');
assert.ok(displayPanel.screenTimeoutSetting === 60);
displayPanel.tapScreenTimeoutSelectOption('2 minutes');
assert.ok(displayPanel.screenTimeoutSetting === 120);
displayPanel.tapScreenTimeoutSelectOption('5 minutes');
assert.ok(displayPanel.screenTimeoutSetting === 300);
displayPanel.tapScreenTimeoutSelectOption('10 minutes');
assert.ok(displayPanel.screenTimeoutSetting === 600);
displayPanel.tapScreenTimeoutSelectOption('never');
assert.ok(displayPanel.screenTimeoutSetting === 0);
});
});
});
});

View file

@ -0,0 +1,35 @@
'use strict';
var Settings = require('../app/app'),
assert = require('assert');
marionette('manipulate do not track settings', function() {
var client = marionette.client({
desiredCapabilities: { raisesAccessibilityExceptions: false }
});
var settingsApp;
var doNotTrackPanel;
setup(function() {
settingsApp = new Settings(client);
settingsApp.launch();
// Navigate to the Do Not Track menu
doNotTrackPanel = settingsApp.doNotTrackPanel;
});
test('check do not track initial state', function() {
assert.ok(
!doNotTrackPanel.isDoNotTrackEnabled,
'do not track is disabled by default'
);
});
test('enable do not track', function() {
doNotTrackPanel.enableDoNotTrack();
assert.ok(
doNotTrackPanel.isDoNotTrackEnabled,
'do not track has been enabled'
);
});
});

View file

@ -0,0 +1,42 @@
'use strict';
var Settings = require('../app/app'),
assert = require('assert');
marionette('manipulate hotspot wifi settings', function() {
var client = marionette.client({
desiredCapabilities: { raisesAccessibilityExceptions: false }
});
var settingsApp;
var hotspotPanel;
var hotspotSettingsPanel;
setup(function() {
settingsApp = new Settings(client);
settingsApp.launch();
// Navigate to the Hotspot Settings menu
hotspotPanel = settingsApp.hotspotPanel;
hotspotSettingsPanel = settingsApp.hotspotSettingsPanel;
});
test('resets settings for second load', function() {
var defaultSsid = hotspotSettingsPanel.ssid;
assert.ok(
defaultSsid,
'ssid is provided by default'
);
hotspotSettingsPanel.ssid = 'Updated SSID ' + Date.now();
hotspotSettingsPanel.back();
hotspotSettingsPanel = settingsApp.hotspotSettingsPanel;
assert.equal(
defaultSsid,
hotspotSettingsPanel.ssid,
'ssid is reset to setting'
);
});
});

View file

@ -0,0 +1,61 @@
'use strict';
var Settings = require('../app/app');
var assert = require('assert');
marionette('Uninstall an ime app', function() {
var IME_TEST_APP_ORIGIN = 'app://imetestapp.gaiamobile.org';
var IME_TEST_APP_NAME = 'LOL Keyboard';
var preloadApps = {};
// And a testing 3rd-party IME app
preloadApps[IME_TEST_APP_ORIGIN] = __dirname + '/../../fixtures/imetestapp';
var client = marionette.client({
profile: {
apps: preloadApps
}
});
var confirmDialog;
var settingsApp;
var appPermissionPanel;
var system;
setup(function() {
system = client.loader.getAppClass('system');
system.waitForFullyLoaded();
confirmDialog = client.loader.getAppClass('system', 'confirm_dialog');
settingsApp = new Settings(client);
settingsApp.launch();
appPermissionPanel = settingsApp.appPermissionPanel;
});
test('Uninstall the preload IME Test App', function() {
function findImeTestApp(element) {
return IME_TEST_APP_NAME === element.text();
}
// Find the IME Test app we preload.
var apps = appPermissionPanel.appList.filter(findImeTestApp);
// Make sure LOL Keyboard is listed.
assert.equal(apps.length, 1);
var imeAppItem = apps[0];
imeAppItem.click();
imeAppItem.tap(5, 5);
appPermissionPanel.uninstallButton.click();
// confirm to uninstall
client.switchToFrame();
confirmDialog.confirm('remove');
// Switch back to settings app
settingsApp.switchTo();
// Make sure LOL Keyboard is not listed in app list
apps = appPermissionPanel.appList.filter(findImeTestApp);
assert.equal(apps.length, 0);
});
});

View file

@ -0,0 +1,103 @@
'use strict';
var Settings = require('../app/app'),
assert = require('assert');
marionette('improve b2g', function() {
var client = marionette.client({
desiredCapabilities: { raisesAccessibilityExceptions: false }
});
var settingsApp;
var improvePanel;
var feedbackPanel;
setup(function() {
settingsApp = new Settings(client);
settingsApp.launch();
// Navigate to the Improve panel
improvePanel = settingsApp.improvePanel;
});
suite('improve page', function() {
test('enable always send report', function() {
// make sure the item displaying on the screen
improvePanel.enableAskEachTime();
improvePanel.enableAlwaysSendReport();
assert.ok(true,
'always send report is enabled');
});
test('enable never send report', function() {
improvePanel.enableNeverSendReport();
assert.ok(true,
'never send report is enabled');
});
test('enable ask each time', function() {
improvePanel.enableAskEachTime();
assert.ok(true,
'ask each time is enabled');
});
});
suite('choose feedback page', function() {
setup(function() {
// Navigate to the feedback panel
feedbackPanel = settingsApp.feedbackPanel;
improvePanel.enterFeedbackPanel();
feedbackPanel.isRendered();
});
test('entering into send feedback panel and happy', function() {
feedbackPanel.enterWithHappy();
assert.ok(true,
'|happy| feedback entry is ok');
});
test('entering into send feedback panel and sad', function() {
feedbackPanel.enterWithSad();
assert.ok(true,
'|sad| feedback entry is ok');
});
});
suite('send feedback page', function() {
var feedbackPanel;
setup(function() {
feedbackPanel = settingsApp.feedbackPanel;
improvePanel.enterFeedbackPanel();
feedbackPanel.isRendered();
feedbackPanel.enterWithHappy();
});
test('empty message', function() {
feedbackPanel.sendFeedback();
assert.equal(feedbackPanel.alertMsg,
'Sorry, the system can’t send your suggestion ' +
'because the comment field is empty. Please enter ' +
'some text and try again.'
);
});
// disabled at bug #981993 because of intermittent failures
test.skip('open email column but left it empty', function() {
feedbackPanel.inputMsgToDialog('test');
feedbackPanel.openEmailCol();
feedbackPanel.sendFeedback();
assert.equal(feedbackPanel.alertMsg,
'Sorry, the system can’t send your suggestion ' +
'because the email address is missing or due to ' +
'a formatting error. Please use a valid email address ' +
'and try again.');
});
// disabled at bug #981993 because of intermittent failures
test.skip('click back and enter again, the msg should be the same',
function() {
var msg = 'test';
feedbackPanel.inputMsgToDialog(msg);
feedbackPanel.tapFeedbackBack();
feedbackPanel.enterWithHappy();
assert.equal(feedbackPanel.discription, msg);
});
});
});

View file

@ -0,0 +1,108 @@
'use strict';
var Settings = require('../app/app');
var SettingsKeyboardApp = require('../app/keyboard_app');
var KeyboardTestApp = require(
'../../../../keyboard/test/marionette/lib/keyboard_test_app');
var KeyboardApp = require('../../../../keyboard/test/marionette/lib/keyboard');
var assert = require('assert');
marionette('manipulate keyboard settings', function() {
var client;
var settingsApp;
var settingsKeyboardApp;
var keyboardTestApp;
var keyboardApp;
var keyboardPanel;
var systemInputMgmt;
var apps = {};
apps[KeyboardTestApp.ORIGIN] =
__dirname + '/../../../../keyboard/test/marionette/apps/keyboardtestapp';
client = marionette.client({
profile: {
apps: apps,
prefs: {
'focusmanager.testmode': true
},
settings: {
'lockscreen.enabled': false,
'ftu.manifestURL': null
}
},
desiredCapabilities: { raisesAccessibilityExceptions: false }
});
setup(function() {
settingsKeyboardApp = new SettingsKeyboardApp(client);
settingsApp = new Settings(client);
keyboardApp = new KeyboardApp(client);
keyboardTestApp = new KeyboardTestApp(client);
settingsApp.launch();
// Navigate to the keyboard menu
keyboardPanel = settingsApp.keyboardPanel;
});
test('Launch built-in keyboard\'s settings page', function() {
keyboardPanel.tapBuiltInKeyboardItem();
settingsKeyboardApp.switchToSettings();
// Uncheck the vibration menu item and ensure mozSetting is set.
settingsKeyboardApp.clickVibrationOption();
assert.equal(settingsKeyboardApp.vibrationFromMozSettings, false);
settingsKeyboardApp.goBackToSettingsApp();
// switch back to settings frame and verify
settingsApp.switchTo();
assert.equal(keyboardPanel.header.getAttribute('action'), 'back');
// Check the icon is not shown as [X], which is for dialog style.
assert.ok(!keyboardPanel.isDialog());
});
test('Change keyboard language', function() {
// Keyboard location of special character ñ
var specialKeySelector = 'button[data-keycode-upper="209"]';
// Tap 'Select Keyboards' button
keyboardPanel.tapSelectKeyboards();
// Select keyboard language, then click back to make it "stick"
keyboardPanel.selectLayout('Espa\u00F1ol');
keyboardPanel.tapBackButton();
settingsApp.close();
// Launch the keyboard test app to verify the keyboard layout
keyboardTestApp.launch();
keyboardTestApp.textInput.tap();
// Switch to keyboard frame
systemInputMgmt = client.loader.getAppClass('system', 'input_management');
systemInputMgmt.waitForKeyboardFrameDisplayed();
systemInputMgmt.switchToActiveKeyboardFrame();
// Switch language, and check if keyboard language is indeed 'Es'
// Need to wait for the change before making an assertion.
keyboardApp.imeSwitchingKey.tap();
client.waitFor(function() {
return (keyboardApp.imeSwitchingKey.getAttribute('aria-label') === 'Es');
});
assert.equal(keyboardApp.imeSwitchingKey.getAttribute('aria-label'), 'Es');
// Try typing the special character
// The keyboardApp.type() method uses long-press, which is not normal user
// behaviour, and English keyboard would also be able to type it out.
client.waitFor(function() {
return client.findElement(specialKeySelector).displayed();
});
client.findElement(specialKeySelector).tap();
// Verify the typed key is correct
client.switchToFrame();
keyboardTestApp.launch();
assert.equal(keyboardTestApp.textInput.getAttribute('value'), '\u00F1',
'\u00F1 is typed out');
});
});

View file

@ -0,0 +1,142 @@
'use strict';
/* global Event */
var Settings = require('../app/app'),
assert = require('assert');
marionette('manipulate language settings', function() {
var client = marionette.client();
var settingsApp;
setup(function() {
settingsApp = new Settings(client);
settingsApp.launch();
});
suite('change language', function() {
var languagePanel;
setup(function() {
client.settings.set('devtools.pseudolocalization.enabled', true);
languagePanel = settingsApp.languagePanel;
languagePanel.setupDefaultLanguage();
});
teardown(function() {
client.settings.set('devtools.pseudolocalization.enabled', false);
});
test('label in the panel is translated.', function() {
languagePanel.currentLanguage = 'accented';
assert.equal(languagePanel.currentLanguage, 'accented');
languagePanel.currentLanguage = 'bidi';
assert.equal(languagePanel.currentLanguage, 'bidi');
languagePanel.currentLanguage = 'english';
assert.equal(languagePanel.currentLanguage, 'english');
});
test('mozSettings value is correct', function() {
languagePanel.currentLanguage = 'accented';
assert.equal(languagePanel.currentLanguageFromMozSettings,
'fr-x-psaccent');
languagePanel.currentLanguage = 'bidi';
assert.equal(languagePanel.currentLanguageFromMozSettings,
'ar-x-psbidi');
languagePanel.currentLanguage = 'english';
assert.equal(languagePanel.currentLanguageFromMozSettings,
'en-US');
});
test('sample format is translated', function() {
languagePanel.currentLanguage = 'accented';
assert.ok(languagePanel.isSampleFormatTranslated('accented'));
languagePanel.currentLanguage = 'bidi';
assert.ok(languagePanel.isSampleFormatTranslated('bidi'));
languagePanel.currentLanguage = 'english';
assert.ok(languagePanel.isSampleFormatTranslated('english'));
});
});
suite('pseudolanguages', function() {
var languagePanel;
var quickly;
setup(function() {
// this allows waitForElement* methods to fail quickly
quickly = client.scope({ searchTimeout: 50 });
quickly.helper.client = quickly;
languagePanel = settingsApp.languagePanel;
languagePanel.setupDefaultLanguage();
languagePanel.back();
});
test('the setting is off', function() {
quickly.settings.set('devtools.pseudolocalization.enabled', false);
languagePanel = settingsApp.languagePanel;
quickly.helper.waitForElement('option[value="en-US"]');
quickly.helper.waitForElementToDisappear('option[value="fr-x-psaccent"]');
assert.ok(true, 'fr-x-psaccent is not listed');
});
test('turning the setting on and off', function() {
// 1. turn the setting on
quickly.settings.set('devtools.pseudolocalization.enabled', true);
languagePanel = settingsApp.languagePanel;
quickly.helper.waitForElement('option[value="fr-x-psaccent"]');
assert.ok(true, 'fr-x-psaccent is listed');
quickly.helper.waitForElement('option[value="ar-x-psbidi"]');
assert.ok(true, 'ar-x-psbidi is listed');
languagePanel.currentLanguage = 'accented';
languagePanel.back();
// 2. turn the setting off
quickly.settings.set('devtools.pseudolocalization.enabled', false);
languagePanel = settingsApp.languagePanel;
quickly.helper.waitForElement('option[value="fr-x-psaccent"]');
assert.ok(true, 'fr-x-psaccent is listed');
quickly.helper.waitForElementToDisappear('option[value="ar-x-psbidi"]');
assert.ok(true, 'ar-x-psbidi is not listed');
languagePanel.currentLanguage = 'english';
// 3. when a new language is chosen, pseudolocales are removed
// from the select dropdown
// XXX For this test we need to emulate a blur event which is
// normally emitted when the user confirms the choice of the
// language. In Marionette, the event is not dispatched. See
// bug: https://bugzil.la/1050206
var selectEl = languagePanel.findElement('languageChangeSelect');
selectEl.scriptWith(function(selectEl) {
var evt = new Event('blur', {
'view': window,
'bubbles': true,
'cancelable': true
});
selectEl.dispatchEvent(evt);
});
quickly.helper.waitForElementToDisappear('option[value="fr-x-psaccent"]');
assert.ok(true, 'fr-x-psaccent is not listed');
languagePanel.back();
// 4. reopen the panel
languagePanel = settingsApp.languagePanel;
quickly.helper.waitForElementToDisappear('option[value="fr-x-psaccent"]');
assert.ok(true, 'fr-x-psaccent is not listed');
});
});
});

View file

@ -0,0 +1,19 @@
[sound_settings_test.js]
[language_settings_test.js]
[root_settings_test.js]
[bluetooth_settings_test.js]
[hotspot_wifi_settings_test.js]
[keyboard_settings_test.js]
[app_permission_settings_test.js]
[battery_settings_test.js]
[support_settings_test.js]
[media_storage_settings_test.js]
[notifications_settings_test.js]
[do_not_track_settings_test.js]
[improve_settings_test.js]
[display_settings_test.js]
[app_storage_settings_test.js]
[message_settings_test.js]
[airplane_mode_settings_test.js]
[ime_uninstallation_test.js]
[screen_lock_settings_test.js]

View file

@ -0,0 +1,51 @@
'use strict';
var Settings = require('../app/app'),
assert = require('assert');
marionette('manipulate media storage settings', function() {
var client = marionette.client();
var settingsApp;
var mediaStoragePanel;
setup(function() {
settingsApp = new Settings(client);
settingsApp.launch();
// Navigate to the Media storage menu
mediaStoragePanel = settingsApp.mediaStoragePanel;
});
suite('check media storage basics', function() {
test.skip('check storage data contain numbers', function() {
assert.ok(mediaStoragePanel.containNumberInMusicSpace);
assert.ok(mediaStoragePanel.containNumberInPictureSpace);
assert.ok(mediaStoragePanel.containNumberInVideoSpace);
});
test.skip('check free/total space contain numbers', function() {
assert.ok(mediaStoragePanel.containNumberInFreeSpace);
assert.ok(mediaStoragePanel.containNumberInTotalSpace);
});
// Since 'canBeFormatted' attribute is false on b2g desktop,
// there is no foramt button for the functionality.
// So we have to skip over the test case.
// Once bug 1055992 fixed, we can re-enable the test case.
test.skip('tap on Format SD card button', function() {
mediaStoragePanel.tapOnFormatSdcardButton();
assert.ok(
mediaStoragePanel.isFormatSdcardDialogShowed,
'will show dialog'
);
});
});
suite('check media storage advanced', function() {
test('check initial state', function() {
assert.ok(
!mediaStoragePanel.isMediaLocationSelectorEnabled,
'Media location selector is disabled by default'
);
});
});
});

View file

@ -0,0 +1,71 @@
'use strict';
var Settings = require('../app/app');
var assert = require('assert');
marionette('message settings', function() {
var client = marionette.client({
desiredCapabilities: { raisesAccessibilityExceptions: false }
});
var settingsApp;
var messagePanel;
setup(function() {
settingsApp = new Settings(client);
settingsApp.launch();
messagePanel = settingsApp.messagePanel;
});
suite('click on all menuItems', function() {
setup(function() {
messagePanel.initialMessagingSettings();
messagePanel.toggleMenuItem('deliveryReport', true);
messagePanel.toggleMenuItem('readReport', true);
messagePanel.toggleMenuItem('wapPush', true);
messagePanel.toggleMenuItem('cellBroadcast', true);
messagePanel.toggleMenuItem('emergencyAlert', true);
// select specific option
messagePanel.chooseRetrieveMethod('On with roaming');
});
test('we would reflect status on related stuffs', function() {
assert.equal(messagePanel.isChecked('deliveryReportCheckbox'), true);
assert.equal(messagePanel.isChecked('readReportCheckbox'), true);
assert.equal(messagePanel.isChecked('wapPushCheckbox'), true);
assert.equal(messagePanel.isComponentChecked('cellBroadcastCheckbox'),
true);
assert.equal(messagePanel.isComponentChecked('emergencyAlertCheckbox'),
true);
assert.equal(
client.settings.get('ril.sms.requestStatusReport.enabled'), true);
assert.equal(
client.settings.get('ril.mms.requestReadReport.enabled'), true);
assert.equal(
client.settings.get('wap.push.enabled'), true);
assert.equal(
client.settings.get('ril.cellbroadcast.disabled'), false);
assert.equal(
client.settings.get('cmas.enabled')[0], true);
// we will keep its value as `automatic`
assert.equal(messagePanel.getSelectedRetrieveMethod(), 'automatic');
});
});
suite('check Cell Broadcast and CMAS dependency', function() {
setup(function() {
messagePanel.initialMessagingSettings();
messagePanel.toggleMenuItem('emergencyAlert', true);
messagePanel.toggleMenuItem('cellBroadcast', false);
});
test('when CB off, CMAS is also off and disabled', function() {
assert.equal(
client.settings.get('ril.cellbroadcast.disabled'), true);
assert.equal(
client.settings.get('cmas.enabled')[0], false);
assert.equal(messagePanel.isEmergencyAlertCheckboxEnabled, false);
});
});
});

View file

@ -0,0 +1,34 @@
'use strict';
var Settings = require('../app/app'),
assert = require('assert');
marionette('manipulate notifications settings', function() {
var client = marionette.client({
desiredCapabilities: { raisesAccessibilityExceptions: false }
});
var settingsApp;
var notificationsPanel;
setup(function() {
settingsApp = new Settings(client);
settingsApp.launch();
// Navigate to the battery menu
notificationsPanel = settingsApp.notificationsPanel;
});
test('check Show on lockscreen checkbox initial state', function() {
assert.ok(
notificationsPanel.isShowOnLockScreenEnabled,
'Show on lockscreen is disabled by default'
);
});
test('disable Show on lockscreen', function() {
notificationsPanel.tapOnShowOnLockScreen();
assert.ok(
!notificationsPanel.isShowOnLockScreenEnabled,
'Show on lockscreen has been disabled'
);
});
});

View file

@ -0,0 +1,155 @@
'use strict';
var Settings = require('../app/app'),
assert = require('assert');
marionette('check root panel settings', function() {
var client = marionette.client({
desiredCapabilities: { raisesAccessibilityExceptions: false }
});
var settingsApp;
var rootPanel;
var hasNumbers = function(t) {
return /\d/.test(t);
};
setup(function() {
settingsApp = new Settings(client);
});
// Common tests are the tests that use the basic hardware configuration.
suite('common tests', function() {
setup(function() {
// We need to inject the script before launching settings app because it
// access to the objects upon starting up.
client.contentScript.inject(__dirname +
'/../mocks/mock_navigator_moz_wifi_manager.js');
client.contentScript.inject(__dirname +
'/../mocks/mock_navigator_moz_bluetooth.js');
client.settings.set('devtools.pseudolocalization.enabled', true);
settingsApp.launch();
rootPanel = settingsApp.rootPanel;
});
teardown(function() {
client.settings.set('devtools.pseudolocalization.enabled', false);
});
test('check static item descriptions', function() {
// The content of the root panel are delay loaded. We need to wait for
// the actual result.
client.waitFor(function() {
return rootPanel.bluetoothDesc === 'Turned off';
});
// client.waitFor(function() {
// return rootPanel.firefoxAccountDesc === 'Create Account or Sign In';
// });
client.waitFor(function() {
return rootPanel.screenLockDesc === 'Disabled';
});
// client.waitFor(function() {
// return rootPanel.WiFiDesc === 'Not connected';
// });
client.waitFor(function() {
return hasNumbers(rootPanel.applicationStorageDesc);
});
client.waitFor(function() {
return hasNumbers(rootPanel.batteryDesc);
});
// client.waitFor(function() {
// return hasNumbers(rootPanel.mediaStorageDesc);
// });
});
test('language description on the root panel is translated',
function() {
settingsApp.currentLanguage = 'accented';
assert.ok(
rootPanel.isLanguageDescTranslated('accented'),
'language desc was not localized into Accented English');
settingsApp.currentLanguage = 'bidi';
assert.ok(
rootPanel.isLanguageDescTranslated('bidi'),
'language desc was not localized into Bidi English');
settingsApp.currentLanguage = 'english';
assert.ok(
rootPanel.isLanguageDescTranslated('english'),
'language desc was not localized into English');
});
suite('airplane mode', function() {
test('check default value', function() {
assert.ok(!rootPanel.airplaneModeCheckboxChecked,
'airplane mode should be disabled by default');
});
// test('enable airplane mode', function() {
// rootPanel.airplaneMode(true);
// assert.ok(rootPanel.airplaneModeCheckboxChecked,
// 'airplane mode should be enabled');
// });
});
suite('geolocation', function() {
test('check default value', function() {
assert.ok(rootPanel.geolocationCheckboxChecked,
'geolocation should be enabled by default');
});
// test('disable geolocation', function() {
// rootPanel.geolocation(false);
// assert.ok(!rootPanel.geolocationCheckboxChecked,
// 'geolocation should be disabled');
// assert.ok(!rootPanel.geolocationEnabledSetting,
// 'geolocation.enabled should be false');
// });
});
});
suite('sim related tests', function() {
suite('single sim tests', function() {
setup(function() {
client.contentScript.inject(__dirname +
'/../mocks/mock_navigator_moz_mobile_connections.js');
client.contentScript.inject(__dirname +
'/../mocks/mock_navigator_moz_telephony.js');
settingsApp.launch();
rootPanel = settingsApp.rootPanel;
});
test('ensure sim security item visible', function() {
assert.ok(rootPanel.isSimSecurityItemVisible);
});
test('ensure sim manager item invisible', function() {
assert.ok(!rootPanel.isSimManagerItemVisible);
});
});
suite('multiple sim tests', function() {
setup(function() {
client.contentScript.inject(__dirname +
'/../mocks/mock_navigator_moz_mobile_connections_multi.js');
client.contentScript.inject(__dirname +
'/../mocks/mock_navigator_moz_telephony.js');
settingsApp.launch();
rootPanel = settingsApp.rootPanel;
});
test('ensure sim security item visible', function() {
assert.ok(!rootPanel.isSimSecurityItemVisible);
});
test('ensure sim manager item invisible', function() {
assert.ok(rootPanel.isSimManagerItemVisible);
});
});
});
});

View file

@ -0,0 +1,274 @@
'use strict';
var Settings = require('../app/app'),
LockScreen = require('../../../../system/test/marionette/lib/lockscreen'),
LockScreenPasscodeUnlockActions = require(
'../../../../system/test/marionette/lib/' +
'lockscreen_passcode_unlock_actions'),
Promise = require('es6-promise').Promise, // jshint ignore:line
assert = require('assert');
marionette('manipulate screenLock settings', function() {
var client = marionette.client({
desiredCapabilities: { raisesAccessibilityExceptions: false }
});
var settingsApp;
var screenLockPanel;
var lockScreen;
var actions;
setup(function() {
lockScreen = (new LockScreen()).start(client);
settingsApp = new Settings(client);
settingsApp.launch();
// Navigate to the ScreenLock menu
screenLockPanel = settingsApp.screenLockPanel;
screenLockPanel.setupScreenLock();
});
test('lockscreen is enabled', function() {
screenLockPanel.toggleScreenLock();
assert.ok(screenLockPanel.isScreenLockEnabled(),
'screenlock is enabled');
assert.ok(screenLockPanel.isScreenLockChecked(),
'screenlock is checked');
});
test('passcode can\'t be enabled when passcode is wrong', function() {
screenLockPanel.toggleScreenLock();
screenLockPanel.togglePasscodeLock();
screenLockPanel.typePasscode('1234', '5678');
assert.ok(screenLockPanel.isPasscodeNotMatched());
assert.ok(!screenLockPanel.isPasscodeLockEnabled(),
'passcode is not enabled');
assert.ok(!screenLockPanel.isPasscodeChecked(),
'passcode is not checked');
});
// Disabled for intermittent failures. Bug 983171
test.skip(
'passcode is enabled, and we want to disable passcode ' +
'but failed to enter the right code',
function() {
var oldCode = '1234';
var newCode = '4567';
screenLockPanel.toggleScreenLock();
screenLockPanel.togglePasscodeLock();
screenLockPanel.typePasscode(oldCode, oldCode);
screenLockPanel.tapCreatePasscode();
assert.ok(screenLockPanel.isPasscodeLockEnabled(),
'passcode is enabled');
assert.ok(screenLockPanel.isPasscodeChecked(),
'passcode is checked');
screenLockPanel.togglePasscodeLock();
screenLockPanel.typePasscode(newCode);
assert.ok(screenLockPanel.isPasscodeIncorrect(),
'passcode is not correct');
assert.ok(screenLockPanel.isPasscodeLockEnabled(),
'passcode is still enabled');
assert.ok(screenLockPanel.isPasscodeChecked(),
'passcode is still checked');
});
// Disabled for intermittent failures. Bug 983171
test.skip('passcode is enabled, and get disabled successfully', function() {
var rightCode = '1234';
screenLockPanel.toggleScreenLock();
screenLockPanel.togglePasscodeLock();
screenLockPanel.typePasscode(rightCode, rightCode);
screenLockPanel.tapCreatePasscode();
assert.ok(screenLockPanel.isPasscodeLockEnabled(),
'passcode is enabled');
assert.ok(screenLockPanel.isPasscodeChecked(),
'passcode is checked');
screenLockPanel.togglePasscodeLock();
screenLockPanel.typePasscode(rightCode);
assert.ok(!screenLockPanel.isPasscodeLockEnabled(),
'passcode is disabled');
assert.ok(!screenLockPanel.isPasscodeChecked(),
'passcode is not checked');
});
test.skip(
'passcode is enabled and won\'t get disabled if you tap back button ' +
'when we try to disable passcode directly',
function() {
var code = '1234';
screenLockPanel.toggleScreenLock();
screenLockPanel.togglePasscodeLock();
screenLockPanel.typePasscode(code, code);
screenLockPanel.tapCreatePasscode();
screenLockPanel.togglePasscodeLock();
screenLockPanel.tapBackButton();
assert.ok(screenLockPanel.isPasscodeLockEnabled(),
'passcode is still enabled');
assert.ok(screenLockPanel.isPasscodeChecked(),
'passcode is still checked');
});
// Disabled for intermittent failures. Bug 983171
test.skip(
'passcode is enabled and won\'t get disabled if you tap back button ' +
'when we try to disable screenlock directly',
function() {
var code = '1234';
screenLockPanel.toggleScreenLock();
screenLockPanel.togglePasscodeLock();
screenLockPanel.typePasscode(code, code);
screenLockPanel.tapCreatePasscode();
screenLockPanel.toggleScreenLock();
screenLockPanel.tapBackButton();
assert.ok(screenLockPanel.isPasscodeLockEnabled(),
'passcode is still enabled');
assert.ok(screenLockPanel.isPasscodeChecked(),
'passcode is still checked');
});
// Disabled for intermittent failures. Bug 983171
test.skip(
'passcode is enabled and won\'t get disabled if you tap back button ' +
'when we try to edit passcode',
function() {
var code = '1234';
screenLockPanel.toggleScreenLock();
screenLockPanel.togglePasscodeLock();
screenLockPanel.typePasscode(code, code);
screenLockPanel.tapCreatePasscode();
screenLockPanel.tapEditPasscode();
screenLockPanel.tapBackButton();
assert.ok(screenLockPanel.isPasscodeLockEnabled(),
'passcode is still enabled');
assert.ok(screenLockPanel.isPasscodeChecked(),
'passcode is still checked');
});
test(
'passcode is enabled, and we want to edit passcode ' +
'but failed to enter the right code',
function() {
var oldCode = '0000';
var newCode = '4567';
screenLockPanel.toggleScreenLock();
screenLockPanel.togglePasscodeLock();
screenLockPanel.typePasscode(oldCode, oldCode);
screenLockPanel.tapCreatePasscode();
assert.ok(screenLockPanel.isPasscodeLockEnabled(),
'passcode is enabled');
assert.ok(screenLockPanel.isPasscodeChecked(),
'passcode is checked');
screenLockPanel.tapEditPasscode(newCode);
screenLockPanel.waitForElement('passcodeIncorrectLabel');
assert.ok(screenLockPanel.isPasscodeIncorrect(),
'passcode is not correct');
assert.ok(screenLockPanel.isPasscodeLockEnabled(),
'passcode is still enabled');
assert.ok(screenLockPanel.isPasscodeChecked(),
'passcode is still checked');
});
test('passcode is enabled, then get changed successfully', function() {
var oldCode = '1234';
var newCode = '4567';
screenLockPanel.toggleScreenLock();
screenLockPanel.togglePasscodeLock();
screenLockPanel.typePasscode(oldCode, oldCode);
screenLockPanel.tapCreatePasscode();
assert.ok(screenLockPanel.isPasscodeLockEnabled(),
'passcode is enabled');
assert.ok(screenLockPanel.isPasscodeChecked(),
'passcode is checked');
screenLockPanel.tapEditPasscode(oldCode);
screenLockPanel.typePasscode(newCode, newCode);
screenLockPanel.tapChangePasscode();
});
// Disabled for intermittent failures. Bug 983171
test.skip('passcode is enabled, and we want to disable lockscreen directly ' +
'but failed to enter the right code',
function() {
var rightCode = '1234';
var wrongCode = '5678';
screenLockPanel.toggleScreenLock();
screenLockPanel.togglePasscodeLock();
screenLockPanel.typePasscode(rightCode, rightCode);
screenLockPanel.tapCreatePasscode();
screenLockPanel.toggleScreenLock();
screenLockPanel.typePasscode(wrongCode);
assert.ok(screenLockPanel.isPasscodeIncorrect(),
'passcode is not correct');
assert.ok(screenLockPanel.isPasscodeLockEnabled(),
'passcode is still enabled');
assert.ok(screenLockPanel.isPasscodeChecked(),
'passcode is still checked');
});
// Disabled for intermittent failures. Bug 983171
test.skip('passcode is enabled, and we want to disable lockscreen directly',
function() {
var code = '1234';
screenLockPanel.toggleScreenLock();
screenLockPanel.togglePasscodeLock();
screenLockPanel.typePasscode(code, code);
screenLockPanel.tapCreatePasscode();
screenLockPanel.toggleScreenLock();
screenLockPanel.typePasscode(code);
assert.ok(!screenLockPanel.isScreenLockEnabled(),
'screenlock is not enabled');
assert.ok(!screenLockPanel.isScreenLockChecked(),
'screenlock is not checked');
});
test('passcode is enabled, and we want to lock and unlock the device',
function(done) {
var code = '1337';
screenLockPanel.toggleScreenLock();
screenLockPanel.togglePasscodeLock();
screenLockPanel.typePasscode(code, code);
screenLockPanel.tapCreatePasscode();
lockScreen.lock();
new Promise(function(resolve) {
actions = (new LockScreenPasscodeUnlockActions()).start(client);
return lockScreen.slideToUnlock(resolve);
})
.then(function() {
code.split('').forEach(function(keyChar) {
actions.pressKey(keyChar);
});
})
.then(function() {
return actions.waitForUnlock();
})
.then(function() {
settingsApp.switchTo();
assert.ok(screenLockPanel.isScreenLockHeaderLabelVisible(),
'has not returned to settings panel');
})
.then(done)
.catch(done);
});
});

View file

@ -0,0 +1,144 @@
'use strict';
var Settings = require('../app/app'),
assert = require('assert');
marionette('manipulate sound settings', function() {
var client = marionette.client({
desiredCapabilities: { raisesAccessibilityExceptions: false }
});
var settingsApp;
var soundPanel;
setup(function() {
settingsApp = new Settings(client);
client.contentScript.inject(__dirname +
'/../mocks/mock_navigator_moz_telephony.js');
settingsApp.launch();
// Navigate to the sound menu
soundPanel = settingsApp.soundPanel;
});
test('check vibrate mode initial state', function() {
assert.ok(
soundPanel.isVibrateEnabled,
'vibrate mode is enabled by default'
);
});
test('disable vibrate mode', function() {
soundPanel.tapOnVibration();
assert.ok(
!soundPanel.isVibrateEnabled,
'vibrate mode has been disabled'
);
});
/* Volume */
test('change media state', function() {
var value = soundPanel.contentValue;
soundPanel.tapOnMediaSlider();
var content_val = (value === soundPanel.contentValue);
assert.ok(
!content_val,
'media state is changed'
);
});
test('change ringer state', function() {
var value = soundPanel.ringerValue;
soundPanel.tapOnRingerSlider();
var ringer_val = (value === soundPanel.ringerValue);
assert.ok(
!ringer_val,
'ringer state is changed'
);
});
test('change alarm state', function() {
var alarm_value = soundPanel.alarmValue;
soundPanel.tapOnAlarmSlider();
var alarm_val = (alarm_value === soundPanel.alarmValue);
assert.ok(
!alarm_val,
'alarm state is changed'
);
});
test('check default ringtone name', function() {
var ringtone_name = soundPanel.selectedRingtone;
// We can't do `===` because the string may be in RTL marks
assert.ok(ringtone_name.includes('Firefox') ||
ringtone_name.includes('Default'));
});
test('check default alert tone name', function() {
var alerttone_name = soundPanel.selectedAlertTone;
// We can't do `===` because the string may be in RTL marks
assert.ok(alerttone_name.includes('Firefox') ||
alerttone_name.includes('Default'));
});
/* Other sounds */
test('check keypad initial state', function() {
assert.ok(
soundPanel.isKeypadChecked,
'keypad sound is enabled by default'
);
});
test('disable keypad sound', function() {
soundPanel.tapOnKeypad();
assert.ok(
!soundPanel.isKeypadChecked,
'keypad sound has been disabled'
);
});
test('check camera initial state', function() {
assert.ok(
soundPanel.isCameraChecked,
'camera sound is enabled by default'
);
});
test('disable camera sound', function() {
soundPanel.tapOnCamera();
assert.ok(
!soundPanel.isCameraChecked,
'camera sound has been disabled'
);
});
test('check sent message initial state', function() {
assert.ok(
soundPanel.isSentMessageChecked,
'sent message sound is enabled by default'
);
});
test('disable sent message sound', function() {
soundPanel.tapOnSentMessage();
assert.ok(
!soundPanel.isSentMessageChecked,
'sent message sound has been disabled'
);
});
test('check unlock screen initial state', function() {
assert.ok(
!soundPanel.isUnlockScreenChecked,
'unlock screen sound is disabled by default'
);
});
test('enable unlock screen sound', function() {
soundPanel.tapOnUnlockScreen();
assert.ok(
soundPanel.isUnlockScreenChecked,
'unlock screen sound has been enabled'
);
});
});

View file

@ -0,0 +1,124 @@
'use strict';
var Settings = require('../app/app'),
assert = require('assert');
marionette('manipulate support settings', function() {
var client = marionette.client();
var settingsApp;
var supportPanel;
function gotoSupportPanel() {
settingsApp = new Settings(client);
settingsApp.launch();
// Navigate to the Support menu
supportPanel = settingsApp.supportPanel;
}
suite('check support without SIM custom', function() {
setup(function() {
gotoSupportPanel();
});
test('check support initial state', function() {
assert.ok(
!supportPanel.isOnlineSupportEnabled,
'online support is disabled by default'
);
assert.ok(
!supportPanel.isCallSupportEnabled,
'call support is disabled by default'
);
});
});
// suite('check support with SIM custom', function() {
// var onlineSupportTitleKey = 'support.onlinesupport.title';
// var onlineSupportTitleValue = 'Online support';
// var onlineSupportHrefKey = 'support.onlinesupport.href';
// var onlineSupportHrefValue = 'http://www.mozilla.org/';
// var callSupport1TitleKey = 'support.callsupport1.title';
// var callSupport1TitleValue = 'Call support 1';
// var callSupport1HrefKey = 'support.callsupport1.href';
// var callSupport1HrefValue = 'tel:666';
// var callSupport2TitleKey = 'support.callsupport2.title';
// var callSupport2TitleValue = 'Call support 2';
// var callSupport2HrefKey = 'support.callsupport2.href';
// var callSupport2HrefValue = 'tel:999';
// setup(function() {
// client.settings.set(onlineSupportTitleKey, onlineSupportTitleValue);
// client.settings.set(onlineSupportHrefKey, onlineSupportHrefValue);
// client.settings.set(callSupport1TitleKey, callSupport1TitleValue);
// client.settings.set(callSupport1HrefKey, callSupport1HrefValue);
// client.settings.set(callSupport2TitleKey, callSupport2TitleValue);
// client.settings.set(callSupport2HrefKey, callSupport2HrefValue);
// gotoSupportPanel();
// });
// test('check custom support state', function() {
// assert.ok(
// supportPanel.isOnlineSupportEnabled,
// 'online support has been enabled'
// );
// assert.ok(
// supportPanel.isCallSupportEnabled,
// 'call support has been enabled'
// );
// });
// test('check custom online support', function() {
// var onlineSupport = supportPanel.onlineSupport;
// assert.equal(
// onlineSupport.getAttribute('text'),
// onlineSupportTitleValue,
// 'online support title is correct'
// );
// assert.equal(
// onlineSupport.getAttribute('href'),
// onlineSupportHrefValue,
// 'online support href is correct'
// );
// });
// test('check custom call support', function() {
// var callSupports = supportPanel.callSupports;
// assert.equal(
// callSupports.length, 2,
// '2 call numbers should be displayed'
// );
// assert.ok(
// callSupports[0].getAttribute('text').indexOf(
// callSupport1TitleValue +
// ' (' + callSupport1HrefValue + ')') !== -1,
// 'first call support title is correct'
// );
// assert.equal(
// callSupports[0].getAttribute('href'),
// callSupport1HrefValue,
// 'first call support number is valid'
// );
// assert.ok(
// callSupports[1].getAttribute('text').indexOf(
// callSupport2TitleValue +
// ' (' + callSupport2HrefValue + ')') !== -1,
// 'second call support title is correct'
// );
// assert.equal(
// callSupports[1].getAttribute('href'),
// callSupport2HrefValue,
// 'second call support number is valid'
// );
// });
// });
});

View file

@ -0,0 +1,57 @@
'use strict';
var Settings = require('../app/app'),
assert = require('assert');
marionette('manipulate display settings', function() {
var client = marionette.client({
desiredCapabilities: { raisesAccessibilityExceptions: false }
});
var settingsApp;
var usbStoragePanel;
setup(function() {
settingsApp = new Settings(client);
settingsApp.launch();
});
suite('USB storage', function() {
setup(function() {
// Navigate to the usb storage menu
usbStoragePanel = settingsApp.usbStoragePanel;
});
suite('Check USB storage states and enable it', function() {
test('check default value', function() {
assert.ok(
!usbStoragePanel.isUsbEnabledSwitchChecked,
'USB enabled switch is un-checked by default'
);
assert.ok(
!usbStoragePanel.isUmsEnabled,
'The default value for USB setting is false'
);
usbStoragePanel.tapUsbEnabledSwitch();
client.waitFor(function() {
return usbStoragePanel.isUsbEnabledSwitchChecked;
});
usbStoragePanel.tapConfirmButton();
// Need to wait for a moment for the change in settings
client.waitFor(function() {
return usbStoragePanel.isUmsEnabled;
});
assert.ok(
usbStoragePanel.isUsbEnabledSwitchChecked,
'USB enabled switch is checked'
);
assert.ok(
usbStoragePanel.isUmsEnabled,
'USB setting value is changed'
);
});
});
});
});