This repository has been archived by the owner on Jan 6, 2023. It is now read-only.
Initial commit adding integration tests for the webextension. #1332
Merged
vladikoff
merged 12 commits into
mozilla:master
from
jrbenny35:initial-integration-tests
Sep 10, 2018
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
2ad6d6a
Initial commit adding integration tests for the webextension.
jrbenny35 f7caf27
Removed wdio.
jrbenny35 aad1fa4
Add logging to travis runs.
jrbenny35 0106e92
Add geckodriver.
jrbenny35 f367781
Move travis env variables.
jrbenny35 586a99b
Moved travis env variables again.
jrbenny35 42da9ae
more fixes.
jrbenny35 8589360
Renamed step.
jrbenny35 5b3a8e1
Add build step.
jrbenny35 6d558a3
Updates based on review.
jrbenny35 b73f26a
Updates based on review.
jrbenny35 f6b0d5b
Update variable name
jrbenny35 File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,44 @@ | ||
language: node_js | ||
addons: | ||
firefox: latest | ||
node_js: | ||
- "8" | ||
before_install: | ||
- export DISPLAY=:99.0 | ||
- sh -e /etc/init.d/xvfb start | ||
- sleep 3 | ||
- npm i -g npm@6 | ||
script: | ||
- npm run test | ||
env: | ||
global: | ||
- FIREFOX_BINARY: firefox | ||
_aliases: | ||
- &test | ||
before_install: | ||
- sh -e /etc/init.d/xvfb start | ||
- sleep 10 | ||
- &unit-test | ||
env: DISPLAY=:99.0 FIREFOX_BINARY=firefox | ||
addons: | ||
firefox: latest | ||
<<: *test | ||
- &integration-test | ||
env: DISPLAY=:99.0 MOZ_HEADLESS=1 UI_TEST_LOGGING=info GECKODRIVER_VERSION=0.21.0 | ||
addons: | ||
firefox: latest-nightly | ||
before_script: | ||
- wget -O /tmp/geckodriver.tar.gz https://github.com/mozilla/geckodriver/releases/download/v${GECKODRIVER_VERSION}/geckodriver-v${GECKODRIVER_VERSION}-linux64.tar.gz | ||
- mkdir $HOME/geckodriver && tar xvf /tmp/geckodriver.tar.gz -C $HOME/geckodriver | ||
- export PATH=$HOME/geckodriver:$PATH | ||
- firefox --version | ||
- geckodriver --version | ||
- npm run build | ||
<<: *test | ||
|
||
matrix: | ||
jobs: | ||
include: | ||
- script: npm run test | ||
env: | ||
global: | ||
- FIREFOX_BINARY: firefox | ||
before_install: | ||
- export DISPLAY=:99.0 | ||
- sh -e /etc/init.d/xvfb start | ||
- sleep 3 | ||
- script: npm run build | ||
- stage: | ||
node_js: 8 | ||
<<: *unit-test | ||
script: npm run test:karma | ||
- stage: | ||
node_js: 8 | ||
<<: *integration-test | ||
script: npm run test:ui | ||
- stage: | ||
node_js: 8 | ||
script: npm run build | ||
env: BUILD_NOTES | ||
- script: npm run lint | ||
- stage: | ||
node_js: 8 | ||
script: npm run lint | ||
env: LINT | ||
before_script: npm run build | ||
before_install: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
const {By, until, Key} = require('selenium-webdriver'); | ||
const { createLogger, transports } = require('winston'); | ||
const { format } = require('logform'); | ||
const logger = createLogger({ | ||
level: process.env.UI_TEST_LOGGING || 'silent', | ||
format: format.combine( | ||
format.colorize(), | ||
format.align(), | ||
format.printf(info => `${info.level}: ${info.message}`), | ||
), | ||
transports: [ | ||
new transports.Console(), | ||
] | ||
}); | ||
|
||
export default class BasePage { | ||
|
||
constructor(driver, timeout, root) { | ||
this.timeout = (timeout) ? timeout : 10000; | ||
this.driver = driver; | ||
this.by = By; | ||
this.key = Key; | ||
this.logger = logger; | ||
this.root = root; | ||
this.until = until; | ||
this.wait = driver.wait; | ||
} | ||
|
||
/** | ||
* @function waitForPageToLoad | ||
* @param {string} locator CSS Selector of Element. | ||
* @returns {Object} An object representing the page. | ||
* @throws ElementNotFound | ||
*/ | ||
async waitForPageToLoad(locator) { | ||
let element = await this.findElement(locator); | ||
await this.driver.wait(this | ||
.until | ||
.elementIsVisable(element), this.timeout); | ||
return this; | ||
} | ||
|
||
/** | ||
* @function findElement | ||
* @param {string} locator CSS Selector of Element. | ||
* @returns {Object} A WebElement object for element matching selector. | ||
* @throws ElementNotFound | ||
*/ | ||
async findElement(locator) { | ||
this.logger.info(`Looking for element ${locator}`); | ||
this.waitForElement(locator); | ||
this.logger.info(`Found element ${locator}, returning it.`); | ||
if (this.root) { | ||
let root = this.driver.findElement(this.by.css(this.root)); | ||
let element = root.findElement(this.by.css(locator)); | ||
return element; | ||
} else { | ||
let element = await this.driver.findElement(this.by.css(locator)); | ||
return element; | ||
} | ||
} | ||
|
||
/** | ||
* @function findElements | ||
* @param {string} locator CSS Selector of Element. | ||
* @returns {Object} A list of WebElements. | ||
* @throws ElementNotFound | ||
*/ | ||
async findElements(locator) { | ||
this.logger.info(`Looking for element ${locator}`); | ||
this.waitForElement(locator); | ||
this.logger.info(`Found element ${locator}, returning it.`); | ||
if (this.root) { | ||
let root = this.driver.findElement(this.by.css(this.root)); | ||
let elements = root.findElements(this.by.css(locator)); | ||
return elements; | ||
} | ||
return await this.driver.findElements(this.by.css(locator)); | ||
} | ||
|
||
/** | ||
* @function waitForElement | ||
* @param {string} locator CSS Selector of Element. | ||
* @throws ElementNotFound | ||
*/ | ||
async waitForElement(locator) { | ||
this.logger.info(`Waiting for locator ${locator} to appear`); | ||
await this.driver.wait(this | ||
.until | ||
.elementLocated(this | ||
.by | ||
.css(locator)), this.timeout | ||
); | ||
this.logger.info(`Locator ${locator} appeared, returning it.`); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import BasePage from './base_page'; | ||
import NotePage from './note_page'; | ||
|
||
export default class ListPage extends BasePage { | ||
|
||
constructor(driver) { | ||
super(driver); | ||
this.listLocator = '.listView'; | ||
this.newNoteBtnLocator = '.newNoteBtn'; | ||
} | ||
|
||
async waitForPageToLoad() { | ||
this.logger.info('Waiting for list page load.'); | ||
let element = await this.findElement(this.listLocator); | ||
await this.driver.wait(this | ||
.until | ||
.elementIsVisible(element), this.timeout); | ||
this.logger.info('List page loaded.'); | ||
return this; | ||
} | ||
|
||
/** | ||
* @property notesList | ||
* @returns {Object} A list of notes found on the home page | ||
*/ | ||
async notesList(){ | ||
let elements = []; | ||
|
||
await this.findElement(this.listLocator); | ||
await this.findElement('ul'); | ||
for(let item in await this.findElements('li')) { | ||
elements.push(new ListNote(this.driver, item)); | ||
this.logger.info('Created ListNote class.'); | ||
} | ||
return elements; | ||
} | ||
|
||
/** | ||
* @function newNoteButton | ||
* @returns {Object} A Note Page Object | ||
* Clicks the 'new note' button | ||
*/ | ||
async newNoteButton() { | ||
let button = await this.findElement(this.newNoteBtnLocator); | ||
await button.click(); | ||
return await new NotePage(this.driver).waitForPageToLoad(); | ||
} | ||
} | ||
|
||
class ListNote extends ListPage { | ||
|
||
constructor(driver) { | ||
super(driver); | ||
this.titleLocator = 'div > p'; | ||
} | ||
|
||
/** | ||
* @property clickBackButton | ||
* @returns {Object} The title of an individual note | ||
*/ | ||
async getTitle() { | ||
let element = await this.findElement(this.titleLocator); | ||
return element.getText(); | ||
} | ||
|
||
async click() { | ||
let note = await this.driver.findElement(this.by.css(this.titleLocator)); | ||
await note.click(); | ||
return await new NotePage(this.driver).waitForPageToLoad() | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import BasePage from './base_page'; | ||
import ListPage from './list_page'; | ||
|
||
export default class NotePage extends BasePage { | ||
|
||
constructor(driver) { | ||
super(driver); | ||
this.backBtnLocator = '.iconBtn'; | ||
this.editorLocator = '.ck-editor__editable'; | ||
this.noteTitleLocator = 'div > header > p'; | ||
} | ||
|
||
async waitForPageToLoad() { | ||
this.logger.info('Waiting for note page load.'); | ||
let element = await this.findElement(this.backBtnLocator); | ||
await this.driver.wait(this | ||
.until | ||
.elementIsVisible(element), this.timeout); | ||
this.logger.info('Note page loaded.'); | ||
return this; | ||
} | ||
|
||
/** | ||
* @property noteTitle | ||
* @returns {Object} The title of the note | ||
*/ | ||
get noteTitle() { return (async () => | ||
{ | ||
let title = await this.findElement(this.noteTitleLocator); | ||
return title.getText(); | ||
})(); | ||
} | ||
|
||
/** | ||
* @function clickBackButton | ||
* @returns {Object} A List Page object | ||
* Clicks the back button to return to the list page | ||
*/ | ||
async clickBackButton() { | ||
let btn = await this.findElement(this.backBtnLocator); | ||
await btn.click(); | ||
return await new ListPage(this.driver).waitForPageToLoad(); | ||
} | ||
|
||
/** | ||
* @function addNote | ||
* @param {string} title Title of the note you want top add | ||
* @param {string} paragraph Paragraph of the note you want to add | ||
* @returns {Object} An object representing the page. | ||
* @throws ElementNotFound | ||
*/ | ||
async addNote(title, paragraph) { | ||
this.logger.info('Adding a new note'); | ||
let editor = await this.driver.findElement(this.by.css(this.editorLocator)); | ||
await editor.sendKeys(title, this.key.ENTER, paragraph); | ||
// Find note title before we wait for it to change | ||
let thisNoteTitle = await this | ||
.driver | ||
.findElement(this.by.css(this.noteTitleLocator)); | ||
await this.driver.wait( | ||
this.until.elementTextIs(thisNoteTitle, paragraph), | ||
this.timeout | ||
); | ||
this.logger.info('Note added'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/bin/bash | ||
cp ./web-ext-artifacts/*.zip ./firefox_notes.xpi | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could be curious. What if there are multiple ZIP files in the web-ext-artifacts directory? Or is it emptied before every build? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks like it is only done when built, and the build script seems to nuke that |
||
echo "Webextension built and moved to root dir." |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jrbenny35 I get the following
Could we get something like https://github.com/vladikoff/node-geckodriver into the process so it "just works" when I run
test:ui
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is assuming the user is running on Nightly as it seems that plugin keeps up with the most recent releases without a way to install an older version. I'd rather point the user to the geckodriver install and they can install whichever version they need according to their Firefox version.
We could do a docker image, or something like that maybe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm , I think
geckodriver 0.21.0
is backwards compatible, our other Selenium infrastructure didn't have issues running in Stable or Nightly. Especially last couple of versions, don't think they have too many changesThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jrbenny35 any ideas about:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not starting Nightly for me locally
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They kind of work but if someone is using 57, it wouldn't work.
For that error, what is your selenium version?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I installed the stuff package.json. i.e. "selenium-webdriver": "^4.0.0-alpha.1",
do we need some kind of a selenium launcher or do i need to manually run it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's interesting as I have the preference set to ignore signatures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't look right though:
WebDriverError: Could not install add-on: /var/folders/cv/w3cp7lkj6bq70z90s51jllsc0000gn/T/addon-ee6daf6a-c8ae-4451-9bdc-2893432b63f5.xpi
, the xpi should be namedfirefox_notes.xpi
.