Skip to content
This repository has been archived by the owner on Feb 20, 2023. It is now read-only.

Add fxa/sync integration tests #5633

Merged
merged 4 commits into from
Oct 11, 2019

Conversation

isabelrios
Copy link
Contributor

Pull Request checklist

  • Quality: This PR builds and passes detekt/ktlint checks (A pre-push hook is recommended)
  • Tests: This PR includes thorough tests or an explanation of why it does not
  • [-] Screenshots: This PR includes screenshots or GIFs of the changes made or an explanation of why it does not
  • [-] Accessibility: The code in this PR follows accessibility best practices or does not include any user facing features

This PR tries to add new tests, sync integration tests, to check the sync process Desktop<->Fenix, first for Bookmarks and in the future for more.

@isabelrios
Copy link
Contributor Author

@rpappalax, @npark-mozilla once the checks are green I would like to ask you to take a first look at the changes in this PR about adding the sync integration tests.
In case of questions please let me know or check the doc with all the implementation details for more info...
Thanks!!

@@ -0,0 +1 @@
pytest-28f90ad8b4@restmail.net
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this is not a permanent account, while running the tests via pipenv run pytesta new account will be created, written in this file and read after that for the test to be used to sync in Fenix app.
Same for the password below.

@@ -33,6 +33,9 @@ gcloud:
- /sdcard/screenshots
performance-metrics: true

test-targets:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding this line and below we avoid running these sync integration tests as part as the regular UI tests.

import mozilla.components.service.fretboard.ExperimentDescriptor

const val EXPERIMENTS_JSON_FILENAME = "experiments.json"
const val EXPERIMENTS_BASE_URL = "https://firefox.settings.services.mozilla.com/v1"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks like a production server. Is that intentional for this test?

import mozilla.components.service.fxa.ServerConfig

object FxaServer {
const val CLIENT_ID = "a2270f727f45f648"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will this CLIENT_ID also be replaced by a dynamic one? (same as: https://github.com/mozilla-mobile/fenix/pull/5633/files/b6603729b13964d8f52aa06342a74601f2bf6cd3#r329536741)? It's OK to hard code these if necessary, but it would be more brittle. Esp. on the stage server

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implementation is similar, using same CLIENT_ID for the non test part, the regular FxaServer.kt. But I can check if this can be changed

pytest-fxa = "*"
pytest-html = "*"
pytest-metadata = "*"
requests = "*"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you not want to pin down these version numbers for stability?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have had this for the iOS tests for long time and did not face any stability issues...but if you prefer I change that, I can look into that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pipfile.lock is checked in, which should pin down dependency versions already.

fun checkBookmarkFromDesktopTest() {
signInFxSync()
tapReturnToPreviousApp()
sleep(5000)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i imagine you're going to refine this later, but I recommend creating a constant for this in the helpers. We currently have a few wait times defined in https://github.com/mozilla-mobile/fenix/blob/master/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt which was created for Mock server assets / functions. With my next PR, I'll be adding a more generic https://github.com/mozilla-mobile/fenix/blob/master/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt which would be for misc functions and constants. We could eventually migrate our constants there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, these tests, except for the first one are commented out at the moment and will need a little bit of work once the environment is set up and the first test is constantly passing. I just drafted them to have an idea about how the test suite will look like.

fun checkHistoryFromDeviceTest() {
tapInToolBar()
typeInToolBar()
sleep(3000)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see above comment

val emailInput = mDevice.findObject(UiSelector()
.instance(0)
.className(EditText::class.java))
emailInput.waitForExists(1000)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will change that to use the constant in helpers. Sorry I forgot about that.

tapReturnToPreviousApp()
homeScreen {
}.openThreeDotMenu {}
libraryButton()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is just a style preference, but I put these methods inside the bracket of openThreeDotMenu to show that these actions are happening within the three dot menu dialog. For me it's more easier to read.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right, when I created this PR those options were not added to the robot menu yet, so I added functions at the end of the test. I will replace them with the actions from robot!

val signInButton = mDevice.findObject(UiSelector()
.instance(0)
.className(Button::class.java))
signInButton.waitForExists(10000)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use constants


fun tapOnContinueButton() {
val continueButton = mDevice.findObject(By.res("submit-btn"))
continueButton.clickAndWait(Until.newWindow(), 50000)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use constants

fun tapOnSygIn() {
mDevice.pressEnter()
mDevice.wait(Until.findObjects(By.text("Sign in")), 3000)
val signInButton = mDevice.findObject(UiSelector()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use constants

fun redirectUrl(context: Context) = if (context.isInExperiment(Experiments.asFeatureWebChannelsDisabled)) {
REDIRECT_URL
} else {
"urn:ietf:wg:oauth:2.0:oob:oauth-redirect-webchannel"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we put this as a constant?

Copy link

@nojunpark nojunpark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

other than minor style suggestion, LGTM

@codecov-io
Copy link

codecov-io commented Oct 2, 2019

Codecov Report

Merging #5633 into master will increase coverage by 0.01%.
The diff coverage is 61.11%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master    #5633      +/-   ##
============================================
+ Coverage     14.36%   14.37%   +0.01%     
- Complexity      322      326       +4     
============================================
  Files           257      258       +1     
  Lines         10539    10543       +4     
  Branches       1538     1537       -1     
============================================
+ Hits           1514     1516       +2     
- Misses         8899     8901       +2     
  Partials        126      126
Impacted Files Coverage Δ Complexity Δ
...main/java/org/mozilla/fenix/components/Services.kt 0% <0%> (ø) 0 <0> (ø) ⬇️
...ain/java/org/mozilla/fenix/components/FxaServer.kt 100% <100%> (ø) 4 <4> (?)
...org/mozilla/fenix/components/BackgroundServices.kt 46.93% <54.54%> (-1.58%) 4 <0> (ø)
app/src/main/java/org/mozilla/fenix/Config.kt 0% <0%> (ø) 0% <0%> (ø) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update bf5b4fe...0e3148f. Read the comment docs.

@isabelrios isabelrios force-pushed the sync-integration-tests branch 2 times, most recently from 55a641d to edb879c Compare October 2, 2019 19:55
@isabelrios isabelrios marked this pull request as ready for review October 3, 2019 10:37
@isabelrios
Copy link
Contributor Author

@csadilek asking for your review since you are familiar with all the changes at least for a first deep look..thanks!

Copy link
Contributor

@csadilek csadilek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Just some nits (missing license headers, some KDocs) to address before landing. Thanks for moving this forward!

@@ -0,0 +1,21 @@
package org.mozilla.fenix.components
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a license header here :).

import mozilla.components.service.fxa.ServerConfig
import org.mozilla.fenix.Experiments
import org.mozilla.fenix.isInExperiment

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add some KDocs here e.g.

/**
 * Utility to configure Firefox Account servers.
 */

docs/syncIntegrationTests.md Show resolved Hide resolved
@@ -0,0 +1,26 @@
### Sync Integration Tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for writing these docs!

@@ -0,0 +1,17 @@
package org.mozilla.fenix.components
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We forgot the license header.

import android.content.Context
import mozilla.components.service.fxa.ServerConfig

object FxaServer {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add some KDocs, see my comment below.

Copy link
Contributor

@grigoryk grigoryk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really neat. How do you ensure that FxA signin verification won't be necessary during a test?

pytest-fxa = "*"
pytest-html = "*"
pytest-metadata = "*"
requests = "*"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pipfile.lock is checked in, which should pin down dependency versions already.


fun Context.isInExperiment(descriptor: ExperimentDescriptor): Boolean =
if (descriptor.name == "asFeatureWebChannelsDisabled")
true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only reason webchannel stuff didn't work is because we didn't whitelist stage FxA server in the webchannel extension manifest file. We certainly do want these tests to exercise webchannel flow, since that's the flow we ship by default. This can be an easy follow-up PR though.

passwordInput.setText(passwordValue)
}

fun tapOnSygIn() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: typo?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right! 🙈

@@ -50,10 +50,10 @@ class BackgroundServicesTest {
val context = mockk<Context>(relaxed = true)

every { context.isInExperiment(eq(Experiments.asFeatureWebChannelsDisabled)) } returns false
assertEquals("urn:ietf:wg:oauth:2.0:oob:oauth-redirect-webchannel", BackgroundServices.redirectUrl(context))
// assertEquals("urn:ietf:wg:oauth:2.0:oob:oauth-redirect-webchannel", BackgroundServices.redirectUrl(context))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems wrong. Why did you need to disable these tests?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah this was likely because redirectUrl is no longer a function on BackgroundServices. Didn't notice this was commented out. So, we can change that to FxaServer.redirectUrl(context) now and it should work again.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, sorry about that I commented it so that building on TC did not complain and forgot to fix. Fixing...

@isabelrios
Copy link
Contributor Author

isabelrios commented Oct 4, 2019

This is really neat. How do you ensure that FxA signin verification won't be necessary during a test?

The verification happens after the account is created with fxacli tool in plugin.py (part of the code):

....
fxa_account = FxAccount(email=account.email, password=password)
    try:
        session = fxa_client.create_account(fxa_account.email,
                                            fxa_account.password)
        logger.info('Created: {}'.format(fxa_account))
        account.fetch()
        message = account.wait_for_email(
            lambda m: 'x-verify-code' in m['headers'] and
            session.uid == m['headers']['x-uid']
        )
        assert (message is not None), 'Verification email not found.'
        session.verify_email_code(message['headers']['x-verify-code'])
        logger.info('Verified: {}'.format(fxa_account))
        yield fxa_account
....

In the logs you can see something as:

root:plugin.py:93 Created: FxAccount(email='pytest-9e83976acb@restmail.net', password='cwyOfVGK')
root:plugin.py:101 Verified: FxAccount(email='pytest-9e83976acb@restmail.net', password='cwyOfVGK')

When the test finishes, the account is removed.

@isabelrios isabelrios changed the title (WIP) Add fxa/sync integration tests Add fxa/sync integration tests Oct 7, 2019
fixing Jenkins path to tests and clean tests

commenting future tests and adding doc with info about the tests
@sblatz
Copy link
Contributor

sblatz commented Oct 8, 2019

Is this ready to land? This PR has been up and approved for a while. Want to make sure I don't merge it before all nits have been addressed though.

@isabelrios
Copy link
Contributor Author

@sblatz yes, it should be ready, but if you want me to double check with one (or more) reviewers, let me know...

@isabelrios
Copy link
Contributor Author

This is really neat. How do you ensure that FxA signin verification won't be necessary during a test?

The verification happens after the account is created with fxacli tool in plugin.py (part of the code):

....
fxa_account = FxAccount(email=account.email, password=password)
    try:
        session = fxa_client.create_account(fxa_account.email,
                                            fxa_account.password)
        logger.info('Created: {}'.format(fxa_account))
        account.fetch()
        message = account.wait_for_email(
            lambda m: 'x-verify-code' in m['headers'] and
            session.uid == m['headers']['x-uid']
        )
        assert (message is not None), 'Verification email not found.'
        session.verify_email_code(message['headers']['x-verify-code'])
        logger.info('Verified: {}'.format(fxa_account))
        yield fxa_account
....

In the logs you can see something as:

root:plugin.py:93 Created: FxAccount(email='pytest-9e83976acb@restmail.net', password='cwyOfVGK')
root:plugin.py:101 Verified: FxAccount(email='pytest-9e83976acb@restmail.net', password='cwyOfVGK')

When the test finishes, the account is removed.

@grigoryk I replied to your question but did not mention you so not sure if you read it and that answers your question...Thanks!

@isabelrios
Copy link
Contributor Author

Hi @sblatz , what's that bors expected? Should I do something before merging?

@sblatz
Copy link
Contributor

sblatz commented Oct 11, 2019

bors r=csadilek

bors bot pushed a commit that referenced this pull request Oct 11, 2019
5633: Add fxa/sync integration tests r=csadilek a=isabelrios

 Pull Request checklist
<!-- Before submitting the PR, please address each item -->
- [x] **Quality**: This PR builds and passes detekt/ktlint checks (A pre-push hook is recommended)
- [x] **Tests**: This PR includes thorough tests or an explanation of why it does not
- [-] **Screenshots**: This PR includes screenshots or GIFs of the changes made or an explanation of why it does not
- [-] **Accessibility**: The code in this PR follows [accessibility best practices](https://github.com/mozilla-mobile/shared-docs/blob/master/android/accessibility_guide.md) or does not include any user facing features

This PR tries to add new tests, sync integration tests, to check the sync process Desktop<->Fenix, first for Bookmarks and in the future for more.

Co-authored-by: Isabel Rios <isabelrios@mackbookirios.home>
Co-authored-by: isabelrios <isabelrios@gmail.com>
@bors
Copy link

bors bot commented Oct 11, 2019

Build succeeded

  • build-debug
  • lint-compare-locales
  • lint-detekt
  • lint-ktlint
  • lint-lint
  • test-debug
  • test-ui

@bors bors bot merged commit 0e3148f into mozilla-mobile:master Oct 11, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants