2
0
mirror of https://github.com/fork-maintainers/iceraven-browser synced 2024-11-02 03:40:16 +00:00
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>
This commit is contained in:
MozLando 2019-10-11 14:43:39 +00:00
commit f66b9f3e8f
26 changed files with 1311 additions and 28 deletions

46
Jenkinsfile vendored Normal file
View File

@ -0,0 +1,46 @@
pipeline {
agent any
triggers {
cron(env.BRANCH_NAME == 'master' ? 'H 0 * * *' : '')
}
options {
timestamps()
timeout(time: 1, unit: 'HOURS')
}
stages {
stage('test') {
steps {
dir('app/src/androidTest/java/org/mozilla/fenix/syncIntegration') {
sh 'pipenv install'
sh 'pipenv check'
sh 'pipenv run pytest'
}
}
}
}
post {
always {
script {
publishHTML(target: [
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: '/Users/synctesting/.jenkins/workspace/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/SyncIntegrationTests/results',
reportFiles: 'index.html',
reportName: 'HTML Report'])
}
}
failure {
slackSend(
color: 'danger',
message: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
}
fixed {
slackSend(
color: 'good',
message: "FIXED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
}
}
}

View File

@ -125,6 +125,12 @@ android {
flavorDimensions "engine"
sourceSets {
androidTest {
resources.srcDirs += ['src/androidTest/resources']
}
}
productFlavors {
geckoNightly {
dimension "engine"

View File

@ -0,0 +1,33 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix
import android.content.Context
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"
const val EXPERIMENTS_BUCKET_NAME = "main"
// collection name below, see https://bugzilla.mozilla.org/show_bug.cgi?id=1523395 for ownership details
const val EXPERIMENTS_COLLECTION_NAME = "fenix-experiments"
object Experiments {
val AATestDescriptor = ExperimentDescriptor("AAtest")
// application services flag to disable the Firefox Sync syncManager
val asFeatureSyncDisabled = ExperimentDescriptor("asFeatureSyncDisabled")
// application services flag to disable Firefox Accounts pairing button.
val asFeatureFxAPairingDisabled = ExperimentDescriptor("asFeatureFxAPairingDisabled")
// application services flag to disable Firefox Accounts WebChannel integration.
val asFeatureWebChannelsDisabled = ExperimentDescriptor("asFeatureWebChannelsDisabled")
}
val Context.app: FenixApplication
get() = applicationContext as FenixApplication
fun Context.isInExperiment(descriptor: ExperimentDescriptor): Boolean =
if (descriptor.name == "asFeatureWebChannelsDisabled")
true
else
app.fretboard.isInExperiment(this, descriptor)

View File

@ -0,0 +1,25 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.components
import android.content.Context
import mozilla.components.service.fxa.ServerConfig
/**
* Utility to configure Firefox Account stage servers.
*/
object FxaServer {
const val CLIENT_ID = "a2270f727f45f648"
const val REDIRECT_URL = "https://accounts.stage.mozaws.net/oauth/success/$CLIENT_ID"
@Suppress("UNUSED_PARAMETER")
fun redirectUrl(context: Context) = REDIRECT_URL
@Suppress("UNUSED_PARAMETER")
fun config(context: Context): ServerConfig {
return ServerConfig.dev(CLIENT_ID, REDIRECT_URL)
}
}

View File

@ -0,0 +1,22 @@
[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true
name = "pypi"
[packages]
fxapom = "*"
mozdownload = "*"
mozinstall = "*"
mozprofile = "*"
mozrunner = "*"
mozversion = "*"
pytest = "*"
pytest-fxa = "*"
pytest-html = "*"
pytest-metadata = "*"
requests = "*"
[dev-packages]
[requires]
python_version = "2.7"

View File

@ -0,0 +1,561 @@
{
"_meta": {
"hash": {
"sha256": "112a12fa2e9e8117b399b60a49b4c8799a614ef655992640c95149bf95f33e8b"
},
"pipfile-spec": 6,
"requires": {
"python_version": "2.7"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.python.org/simple",
"verify_ssl": true
}
]
},
"default": {
"asn1crypto": {
"hashes": [
"sha256:2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87",
"sha256:9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49"
],
"version": "==0.24.0"
},
"atomicwrites": {
"hashes": [
"sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4",
"sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"
],
"version": "==1.3.0"
},
"attrs": {
"hashes": [
"sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79",
"sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399"
],
"version": "==19.1.0"
},
"blessings": {
"hashes": [
"sha256:98e5854d805f50a5b58ac2333411b0482516a8210f23f43308baeb58d77c157d",
"sha256:b1fdd7e7a675295630f9ae71527a8ebc10bfefa236b3d6aa4932ee4462c17ba3",
"sha256:caad5211e7ba5afe04367cdd4cfc68fa886e2e08f6f35e76b7387d2109ccea6e"
],
"version": "==1.7"
},
"certifi": {
"hashes": [
"sha256:59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5",
"sha256:b26104d6835d1f5e49452a26eb2ff87fe7090b89dfcaee5ea2212697e1e1d7ae"
],
"version": "==2019.3.9"
},
"cffi": {
"hashes": [
"sha256:041c81822e9f84b1d9c401182e174996f0bae9991f33725d059b771744290774",
"sha256:046ef9a22f5d3eed06334d01b1e836977eeef500d9b78e9ef693f9380ad0b83d",
"sha256:066bc4c7895c91812eff46f4b1c285220947d4aa46fa0a2651ff85f2afae9c90",
"sha256:066c7ff148ae33040c01058662d6752fd73fbc8e64787229ea8498c7d7f4041b",
"sha256:2444d0c61f03dcd26dbf7600cf64354376ee579acad77aef459e34efcb438c63",
"sha256:300832850b8f7967e278870c5d51e3819b9aad8f0a2c8dbe39ab11f119237f45",
"sha256:34c77afe85b6b9e967bd8154e3855e847b70ca42043db6ad17f26899a3df1b25",
"sha256:46de5fa00f7ac09f020729148ff632819649b3e05a007d286242c4882f7b1dc3",
"sha256:4aa8ee7ba27c472d429b980c51e714a24f47ca296d53f4d7868075b175866f4b",
"sha256:4d0004eb4351e35ed950c14c11e734182591465a33e960a4ab5e8d4f04d72647",
"sha256:4e3d3f31a1e202b0f5a35ba3bc4eb41e2fc2b11c1eff38b362de710bcffb5016",
"sha256:50bec6d35e6b1aaeb17f7c4e2b9374ebf95a8975d57863546fa83e8d31bdb8c4",
"sha256:55cad9a6df1e2a1d62063f79d0881a414a906a6962bc160ac968cc03ed3efcfb",
"sha256:5662ad4e4e84f1eaa8efce5da695c5d2e229c563f9d5ce5b0113f71321bcf753",
"sha256:59b4dc008f98fc6ee2bb4fd7fc786a8d70000d058c2bbe2698275bc53a8d3fa7",
"sha256:73e1ffefe05e4ccd7bcea61af76f36077b914f92b76f95ccf00b0c1b9186f3f9",
"sha256:a1f0fd46eba2d71ce1589f7e50a9e2ffaeb739fb2c11e8192aa2b45d5f6cc41f",
"sha256:a2e85dc204556657661051ff4bab75a84e968669765c8a2cd425918699c3d0e8",
"sha256:a5457d47dfff24882a21492e5815f891c0ca35fefae8aa742c6c263dac16ef1f",
"sha256:a8dccd61d52a8dae4a825cdbb7735da530179fea472903eb871a5513b5abbfdc",
"sha256:ae61af521ed676cf16ae94f30fe202781a38d7178b6b4ab622e4eec8cefaff42",
"sha256:b012a5edb48288f77a63dba0840c92d0504aa215612da4541b7b42d849bc83a3",
"sha256:d2c5cfa536227f57f97c92ac30c8109688ace8fa4ac086d19d0af47d134e2909",
"sha256:d42b5796e20aacc9d15e66befb7a345454eef794fdb0737d1af593447c6c8f45",
"sha256:dee54f5d30d775f525894d67b1495625dd9322945e7fee00731952e0368ff42d",
"sha256:e070535507bd6aa07124258171be2ee8dfc19119c28ca94c9dfb7efd23564512",
"sha256:e1ff2748c84d97b065cc95429814cdba39bcbd77c9c85c89344b317dc0d9cbff",
"sha256:ed851c75d1e0e043cbf5ca9a8e1b13c4c90f3fbd863dacb01c0808e2b5204201"
],
"version": "==1.12.3"
},
"chardet": {
"hashes": [
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
],
"version": "==3.0.4"
},
"configparser": {
"hashes": [
"sha256:8be81d89d6e7b4c0d4e44bcc525845f6da25821de80cb5e06e7e0238a2899e32",
"sha256:da60d0014fd8c55eb48c1c5354352e363e2d30bbf7057e5e171a468390184c75"
],
"markers": "python_version < '3'",
"version": "==3.7.4"
},
"contextlib2": {
"hashes": [
"sha256:509f9419ee91cdd00ba34443217d5ca51f5a364a404e1dce9e8979cea969ca48",
"sha256:f5260a6e679d2ff42ec91ec5252f4eeffdcf21053db9113bd0a8e4d953769c00"
],
"markers": "python_version < '3'",
"version": "==0.5.5"
},
"cryptography": {
"hashes": [
"sha256:24b61e5fcb506424d3ec4e18bca995833839bf13c59fc43e530e488f28d46b8c",
"sha256:25dd1581a183e9e7a806fe0543f485103232f940fcfc301db65e630512cce643",
"sha256:3452bba7c21c69f2df772762be0066c7ed5dc65df494a1d53a58b683a83e1216",
"sha256:41a0be220dd1ed9e998f5891948306eb8c812b512dc398e5a01846d855050799",
"sha256:5751d8a11b956fbfa314f6553d186b94aa70fdb03d8a4d4f1c82dcacf0cbe28a",
"sha256:5f61c7d749048fa6e3322258b4263463bfccefecb0dd731b6561cb617a1d9bb9",
"sha256:72e24c521fa2106f19623a3851e9f89ddfdeb9ac63871c7643790f872a305dfc",
"sha256:7b97ae6ef5cba2e3bb14256625423413d5ce8d1abb91d4f29b6d1a081da765f8",
"sha256:961e886d8a3590fd2c723cf07be14e2a91cf53c25f02435c04d39e90780e3b53",
"sha256:96d8473848e984184b6728e2c9d391482008646276c3ff084a1bd89e15ff53a1",
"sha256:ae536da50c7ad1e002c3eee101871d93abdc90d9c5f651818450a0d3af718609",
"sha256:b0db0cecf396033abb4a93c95d1602f268b3a68bb0a9cc06a7cff587bb9a7292",
"sha256:cfee9164954c186b191b91d4193989ca994703b2fff406f71cf454a2d3c7327e",
"sha256:e6347742ac8f35ded4a46ff835c60e68c22a536a8ae5c4422966d06946b6d4c6",
"sha256:f27d93f0139a3c056172ebb5d4f9056e770fdf0206c2f422ff2ebbad142e09ed",
"sha256:f57b76e46a58b63d1c6375017f4564a28f19a5ca912691fd2e4261b3414b618d"
],
"version": "==2.7"
},
"enum34": {
"hashes": [
"sha256:2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850",
"sha256:644837f692e5f550741432dd3f223bbb9852018674981b1664e5dc339387588a",
"sha256:6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79",
"sha256:8ad8c4783bf61ded74527bffb48ed9b54166685e4230386a9ed9b1279e2df5b1"
],
"markers": "python_version < '3'",
"version": "==1.1.6"
},
"funcsigs": {
"hashes": [
"sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca",
"sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50"
],
"markers": "python_version < '3.0'",
"version": "==1.0.2"
},
"fxapom": {
"hashes": [
"sha256:56fdff0a0f0ea58831337e3a859971f98c59fd028ebc14baa8e37ae08a40efa0",
"sha256:5fb902afaaa9d9b82b5d1d54b9e19f1f4c9be128deb3b0e0ac82a9303f76000f"
],
"index": "pypi",
"version": "==1.10.2"
},
"hawkauthlib": {
"hashes": [
"sha256:935878d3a75832aa76f78ddee13491f1466cbd69a8e7e4248902763cf9953ba9",
"sha256:effd64a2572e3c0d9090b55ad2180b36ad50e7760bea225cb6ce2248f421510d"
],
"version": "==2.0.0"
},
"idna": {
"hashes": [
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
"sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
],
"version": "==2.8"
},
"importlib-metadata": {
"hashes": [
"sha256:a9f185022cfa69e9ca5f7eabfd5a58b689894cb78a11e3c8c89398a8ccbb8e7f",
"sha256:df1403cd3aebeb2b1dcd3515ca062eecb5bd3ea7611f18cba81130c68707e879"
],
"version": "==0.17"
},
"ipaddress": {
"hashes": [
"sha256:64b28eec5e78e7510698f6d4da08800a5c575caa4a286c93d651c5d3ff7b6794",
"sha256:b146c751ea45cad6188dd6cf2d9b757f6f4f8d6ffb96a023e6f2e26eea02a72c"
],
"markers": "python_version < '3'",
"version": "==1.0.22"
},
"more-itertools": {
"hashes": [
"sha256:38a936c0a6d98a38bcc2d03fdaaedaba9f412879461dd2ceff8d37564d6522e4",
"sha256:c0a5785b1109a6bd7fac76d6837fd1feca158e54e521ccd2ae8bfe393cc9d4fc",
"sha256:fe7a7cae1ccb57d33952113ff4fa1bc5f879963600ed74918f1236e212ee50b9"
],
"markers": "python_version <= '2.7'",
"version": "==5.0.0"
},
"mozdevice": {
"hashes": [
"sha256:a7b582331448f28c9f44d5a113a152537e5666b0f5ce1052dc569ab516ec99a8",
"sha256:ec618e0c8000663de99af076f9d5ffdf91eaa81105b75b42a2dbcdb0248c2acb"
],
"version": "==3.0.1"
},
"mozdownload": {
"hashes": [
"sha256:1664b0bf48eab69fafa73d3fc4dc19f4c66dfc21045fab3ca76a29b3eeb31702",
"sha256:d861936c2efcc7620858a097907bfaba5d6d114867b6633e4301da9263627819"
],
"index": "pypi",
"version": "==1.26.0"
},
"mozfile": {
"hashes": [
"sha256:22a43f3bc320c3bda27e54b293c23a51660f4a00ec6959ab70ca6136d702f578",
"sha256:7355643fca705f43d9412d444fb59588fbbd25f0d1e7592b9482f84e3d23bc8e"
],
"version": "==2.0.0"
},
"mozinfo": {
"hashes": [
"sha256:299827c42d54ebb3c3547e299846abd15d22ff677cf6c1adbf54faeb9f024832",
"sha256:4525c26350fb85c26b38c5f853a19f47b17b49a74de363d285d54258972a4cbc"
],
"version": "==1.1.0"
},
"mozinstall": {
"hashes": [
"sha256:219ba7c51308433487b4f30a2615cb9b3ecd40a76b9faf41cf1b1b005bb5dda7"
],
"index": "pypi",
"version": "==2.0.0"
},
"mozlog": {
"hashes": [
"sha256:70ad145949539a3229ffb9b9785058366f2645371a2371cf2ad7c8f2582893ae",
"sha256:d294a71433cca3c873176a87df2ebe8bd632caf63aea4c7c47c1b69700c83dd5"
],
"version": "==4.1"
},
"mozprocess": {
"hashes": [
"sha256:6c984ab251bf0b1d6eef7e4fff87c2c2b60f20953e75eae566cb2d239f39806a",
"sha256:a0fd8367e663d3cac74ee46bffa789667bc8d52f242d81a14522205fa6650cb2"
],
"version": "==1.0.0"
},
"mozprofile": {
"hashes": [
"sha256:65cd29ab2925e40130935b144de80d23270a1bc66bf312b813942b1ba6eb7a76",
"sha256:94a0e14fcf357a90c42418edd414e837ff63bab876ccd51b9a7810d6f3c9fe2d"
],
"index": "pypi",
"version": "==2.2.0"
},
"mozrunner": {
"hashes": [
"sha256:3d3d48ceff333262d4f648314d5c7ac8e1998bf7ed08a7f96ac2a08558958c7b",
"sha256:c98c7a3cabbe7b63348f7c495ed40e75c3946c01896a1bec756e782b30a7b7d5"
],
"index": "pypi",
"version": "==7.4.0"
},
"mozterm": {
"hashes": [
"sha256:b1e91acec188de07c704dbb7b0100a7be5c1e06567b3beb67f6ea11d00a483a4",
"sha256:f5eafa25c23d391e2a2bb1dd45ee928fc9e3c811977a3856b5a5a0778011053c"
],
"version": "==1.0.0"
},
"mozversion": {
"hashes": [
"sha256:35911badaaf02715e56c6062379688724e7afeffc2d25be8567312d24054cdd4",
"sha256:65f41d7dc14002f83d8f147c82ca34f7213ad07065d250939daaeeb3787dc0fa"
],
"index": "pypi",
"version": "==2.1.0"
},
"packaging": {
"hashes": [
"sha256:0c98a5d0be38ed775798ece1b9727178c4469d9c3b4ada66e8e6b7849f8732af",
"sha256:9e1cbf8c12b1f1ce0bb5344b8d7ecf66a6f8a6e91bcb0c84593ed6d3ab5c4ab3"
],
"version": "==19.0"
},
"pathlib2": {
"hashes": [
"sha256:25199318e8cc3c25dcb45cbe084cc061051336d5a9ea2a12448d3d8cb748f742",
"sha256:5887121d7f7df3603bca2f710e7219f3eca0eb69e0b7cc6e0a022e155ac931a7"
],
"markers": "python_version < '3.6'",
"version": "==2.3.3"
},
"pluggy": {
"hashes": [
"sha256:0825a152ac059776623854c1543d65a4ad408eb3d33ee114dff91e57ec6ae6fc",
"sha256:b9817417e95936bf75d85d3f8767f7df6cdde751fc40aed3bb3074cbcb77757c"
],
"version": "==0.12.0"
},
"progressbar2": {
"hashes": [
"sha256:9ecb2d35edaa30ed86eb92fb0135eb19a6ef9b3657be4350cc3d0d3563e6af65",
"sha256:c086fc1f718839c0ec95caaeb7bd5a1d0268a8775960b8f9dee06f2a04c84628"
],
"version": "==3.42.0"
},
"py": {
"hashes": [
"sha256:64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa",
"sha256:dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53"
],
"version": "==1.8.0"
},
"pybrowserid": {
"hashes": [
"sha256:6c227669e87cc25796ae76f6a0ef65025528c8ad82d352679fa9a3e5663a71e3",
"sha256:8e237d6a2bc9ead849a4472a84d3e6a9309bec99cf8e10d36213710dda8df8ca"
],
"version": "==0.14.0"
},
"pycparser": {
"hashes": [
"sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3"
],
"version": "==2.19"
},
"pyfxa": {
"hashes": [
"sha256:616689486d8d63956aa40836cffafde6e7590cdeb200badabaaf3c17d5b26cce"
],
"version": "==0.7.1"
},
"pyparsing": {
"hashes": [
"sha256:1873c03321fc118f4e9746baf201ff990ceb915f433f23b395f5580d1840cb2a",
"sha256:9b6323ef4ab914af344ba97510e966d64ba91055d6b9afa6b30799340e89cc03"
],
"version": "==2.4.0"
},
"pypom": {
"hashes": [
"sha256:4bdd57fceb72d7e6a3645cf6c9322f490d9cfb5d777eac2c851a3b658b813939",
"sha256:6772ec99f0a21a5bdc8c092007a8c813ed18359e67ed70258bbb233df5e28829"
],
"version": "==2.2.0"
},
"pytest": {
"hashes": [
"sha256:1a8aa4fa958f8f451ac5441f3ac130d9fc86ea38780dd2715e6d5c5882700b24",
"sha256:b8bf138592384bd4e87338cb0f256bf5f615398a649d4bd83915f0e4047a5ca6"
],
"index": "pypi",
"version": "==4.5.0"
},
"pytest-fxa": {
"hashes": [
"sha256:778dfdb019f1e0af8744704fe5f7ac5c08fd5d45ff054023b0a18d5f99d737f1",
"sha256:b75967e74e9b2f3ffa5558421fdf61c7fff5948fc9d7e357e7147c682988ecc1"
],
"index": "pypi",
"version": "==1.4.0"
},
"pytest-html": {
"hashes": [
"sha256:648b7ba1d6035cc021d607e9d44f4dc06e916bdb04e09572dd04fb82eecab9ed",
"sha256:a7c65cdd9d5e4d09cef2f500ca801f80c1110204f24e5b84d019c6f919b15e9e"
],
"index": "pypi",
"version": "==1.20.0"
},
"pytest-metadata": {
"hashes": [
"sha256:2071a59285de40d7541fde1eb9f1ddea1c9db165882df82781367471238b66ba",
"sha256:c29a1fb470424926c63154c1b632c02585f2ba4282932058a71d35295ff8c96d"
],
"index": "pypi",
"version": "==1.8.0"
},
"python-utils": {
"hashes": [
"sha256:34aaf26b39b0b86628008f2ae0ac001b30e7986a8d303b61e1357dfcdad4f6d3",
"sha256:e25f840564554eaded56eaa395bca507b0b9e9f0ae5ecb13a8cb785305c56d25"
],
"version": "==2.3.0"
},
"redo": {
"hashes": [
"sha256:36784bf8ae766e14f9db0e377ccfa02835d648321d2007b6ae0bf4fd612c0f94",
"sha256:71161cb0e928d824092a5f16203939bbc0867ce4c4685db263cf22c3ae7634a8"
],
"version": "==2.0.3"
},
"requests": {
"hashes": [
"sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4",
"sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"
],
"index": "pypi",
"version": "==2.22.0"
},
"scandir": {
"hashes": [
"sha256:2586c94e907d99617887daed6c1d102b5ca28f1085f90446554abf1faf73123e",
"sha256:2ae41f43797ca0c11591c0c35f2f5875fa99f8797cb1a1fd440497ec0ae4b022",
"sha256:2b8e3888b11abb2217a32af0766bc06b65cc4a928d8727828ee68af5a967fa6f",
"sha256:2c712840c2e2ee8dfaf36034080108d30060d759c7b73a01a52251cc8989f11f",
"sha256:4d4631f6062e658e9007ab3149a9b914f3548cb38bfb021c64f39a025ce578ae",
"sha256:67f15b6f83e6507fdc6fca22fedf6ef8b334b399ca27c6b568cbfaa82a364173",
"sha256:7d2d7a06a252764061a020407b997dd036f7bd6a175a5ba2b345f0a357f0b3f4",
"sha256:8c5922863e44ffc00c5c693190648daa6d15e7c1207ed02d6f46a8dcc2869d32",
"sha256:92c85ac42f41ffdc35b6da57ed991575bdbe69db895507af88b9f499b701c188",
"sha256:b24086f2375c4a094a6b51e78b4cf7ca16c721dcee2eddd7aa6494b42d6d519d",
"sha256:cb925555f43060a1745d0a321cca94bcea927c50114b623d73179189a4e100ac"
],
"markers": "python_version < '3.5'",
"version": "==1.10.0"
},
"selenium": {
"hashes": [
"sha256:2d7131d7bc5a5b99a2d9b04aaf2612c411b03b8ca1b1ee8d3de5845a9be2cb3c",
"sha256:deaf32b60ad91a4611b98d8002757f29e6f2c2d5fcaf202e1c9ad06d6772300d"
],
"version": "==3.141.0"
},
"six": {
"hashes": [
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
],
"version": "==1.12.0"
},
"treeherder-client": {
"hashes": [
"sha256:4020809424384574277232023c78bcee436ec5474020b4430b4770f0ddd8bba3",
"sha256:db25150480d0501c79b72966899e5c901a5a625e12739389f6bee03273e1d002"
],
"version": "==5.0.0"
},
"urllib3": {
"hashes": [
"sha256:b246607a25ac80bedac05c6f282e3cdaf3afb65420fd024ac94435cabe6e18d1",
"sha256:dbe59173209418ae49d485b87d1681aefa36252ee85884c31346debd19463232"
],
"version": "==1.25.3"
},
"wcwidth": {
"hashes": [
"sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e",
"sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c"
],
"version": "==0.1.7"
},
"webob": {
"hashes": [
"sha256:05aaab7975e0ee8af2026325d656e5ce14a71f1883c52276181821d6d5bf7086",
"sha256:36db8203c67023d68c1b00208a7bf55e3b10de2aa317555740add29c619de12b"
],
"version": "==1.8.5"
},
"zipp": {
"hashes": [
"sha256:8c1019c6aad13642199fbe458275ad6a84907634cc9f0989877ccc4a2840139d",
"sha256:ca943a7e809cc12257001ccfb99e3563da9af99d52f261725e96dfe0f9275bc3"
],
"version": "==0.5.1"
},
"zope.component": {
"hashes": [
"sha256:6edfd626c3b593b72895a8cfcf79bff41f4619194ce996a85bce31ac02b94e55",
"sha256:984a06ba3def0b02b1117fa4c45b56e772e8c29c0340820fbf367e440a93a3a4"
],
"version": "==4.5"
},
"zope.deferredimport": {
"hashes": [
"sha256:2ddef5a7ecfff132a2dd796253366ecf9748a446e30f1a0b3a636aec9d9c05c5",
"sha256:4aae9cbacb2146cca58e62be0a914f0cec034d3b2d41135ea212ca8a96f4b5ec"
],
"version": "==4.3"
},
"zope.deprecation": {
"hashes": [
"sha256:0d453338f04bacf91bbfba545d8bcdf529aa829e67b705eac8c1a7fdce66e2df",
"sha256:f1480b74995958b24ce37b0ef04d3663d2683e5d6debc96726eff18acf4ea113"
],
"version": "==4.4.0"
},
"zope.event": {
"hashes": [
"sha256:69c27debad9bdacd9ce9b735dad382142281ac770c4a432b533d6d65c4614bcf",
"sha256:d8e97d165fd5a0997b45f5303ae11ea3338becfe68c401dd88ffd2113fe5cae7"
],
"version": "==4.4"
},
"zope.hookable": {
"hashes": [
"sha256:22886e421234e7e8cedc21202e1d0ab59960e40a47dd7240e9659a2d82c51370",
"sha256:39912f446e45b4e1f1951b5ffa2d5c8b074d25727ec51855ae9eab5408f105ab",
"sha256:3adb7ea0871dbc56b78f62c4f5c024851fc74299f4f2a95f913025b076cde220",
"sha256:3d7c4b96341c02553d8b8d71065a9366ef67e6c6feca714f269894646bb8268b",
"sha256:4e826a11a529ed0464ffcecf34b0b7bd1b4928dd5848c5c61bedd7833e8f4801",
"sha256:700d68cc30728de1c4c62088a981c6daeaefdf20a0d81995d2c0b7f442c5f88c",
"sha256:77c82a430cedfbf508d1aa406b2f437363c24fa90c73f577ead0fb5295749b83",
"sha256:c1df3929a3666fc5a0c80d60a0c1e6f6ef97c7f6ed2f1b7cf49f3e6f3d4dde15",
"sha256:dba8b2dd2cd41cb5f37bfa3f3d82721b8ae10e492944e48ddd90a439227f2893",
"sha256:f492540305b15b5591bd7195d61f28946bb071de071cee5d68b6b8414da90fd2"
],
"version": "==4.2.0"
},
"zope.interface": {
"hashes": [
"sha256:086707e0f413ff8800d9c4bc26e174f7ee4c9c8b0302fbad68d083071822316c",
"sha256:1157b1ec2a1f5bf45668421e3955c60c610e31913cc695b407a574efdbae1f7b",
"sha256:11ebddf765bff3bbe8dbce10c86884d87f90ed66ee410a7e6c392086e2c63d02",
"sha256:14b242d53f6f35c2d07aa2c0e13ccb710392bcd203e1b82a1828d216f6f6b11f",
"sha256:1b3d0dcabc7c90b470e59e38a9acaa361be43b3a6ea644c0063951964717f0e5",
"sha256:20a12ab46a7e72b89ce0671e7d7a6c3c1ca2c2766ac98112f78c5bddaa6e4375",
"sha256:298f82c0ab1b182bd1f34f347ea97dde0fffb9ecf850ecf7f8904b8442a07487",
"sha256:2f6175722da6f23dbfc76c26c241b67b020e1e83ec7fe93c9e5d3dd18667ada2",
"sha256:3b877de633a0f6d81b600624ff9137312d8b1d0f517064dfc39999352ab659f0",
"sha256:4265681e77f5ac5bac0905812b828c9fe1ce80c6f3e3f8574acfb5643aeabc5b",
"sha256:550695c4e7313555549aa1cdb978dc9413d61307531f123558e438871a883d63",
"sha256:5f4d42baed3a14c290a078e2696c5f565501abde1b2f3f1a1c0a94fbf6fbcc39",
"sha256:62dd71dbed8cc6a18379700701d959307823b3b2451bdc018594c48956ace745",
"sha256:7040547e5b882349c0a2cc9b50674b1745db551f330746af434aad4f09fba2cc",
"sha256:7e099fde2cce8b29434684f82977db4e24f0efa8b0508179fce1602d103296a2",
"sha256:7e5c9a5012b2b33e87980cee7d1c82412b2ebabcb5862d53413ba1a2cfde23aa",
"sha256:81295629128f929e73be4ccfdd943a0906e5fe3cdb0d43ff1e5144d16fbb52b1",
"sha256:95cc574b0b83b85be9917d37cd2fad0ce5a0d21b024e1a5804d044aabea636fc",
"sha256:968d5c5702da15c5bf8e4a6e4b67a4d92164e334e9c0b6acf080106678230b98",
"sha256:9e998ba87df77a85c7bed53240a7257afe51a07ee6bc3445a0bf841886da0b97",
"sha256:a0c39e2535a7e9c195af956610dba5a1073071d2d85e9d2e5d789463f63e52ab",
"sha256:a15e75d284178afe529a536b0e8b28b7e107ef39626a7809b4ee64ff3abc9127",
"sha256:a6a6ff82f5f9b9702478035d8f6fb6903885653bff7ec3a1e011edc9b1a7168d",
"sha256:b639f72b95389620c1f881d94739c614d385406ab1d6926a9ffe1c8abbea23fe",
"sha256:bad44274b151d46619a7567010f7cde23a908c6faa84b97598fd2f474a0c6891",
"sha256:bbcef00d09a30948756c5968863316c949d9cedbc7aabac5e8f0ffbdb632e5f1",
"sha256:d788a3999014ddf416f2dc454efa4a5dbeda657c6aba031cf363741273804c6b",
"sha256:eed88ae03e1ef3a75a0e96a55a99d7937ed03e53d0cffc2451c208db445a2966",
"sha256:f99451f3a579e73b5dd58b1b08d1179791d49084371d9a47baad3b22417f0317"
],
"version": "==4.6.0"
},
"zope.proxy": {
"hashes": [
"sha256:0cbcfcafaa3b5fde7ba7a7b9a2b5f09af25c9b90087ad65f9e61359fed0ca63b",
"sha256:3de631dd5054a3a20b9ebff0e375f39c0565f1fb9131200d589a6a8f379214cd",
"sha256:5429134d04d42262f4dac25f6dea907f6334e9a751ffc62cb1d40226fb52bdeb",
"sha256:563c2454b2d0f23bca54d2e0e4d781149b7b06cb5df67e253ca3620f37202dd2",
"sha256:5bcf773345016b1461bb07f70c635b9386e5eaaa08e37d3939dcdf12d3fdbec5",
"sha256:8d84b7aef38c693874e2f2084514522bf73fd720fde0ce2a9352a51315ffa475",
"sha256:90de9473c05819b36816b6cb957097f809691836ed3142648bf62da84b4502fe",
"sha256:dd592a69fe872445542a6e1acbefb8e28cbe6b4007b8f5146da917e49b155cc3",
"sha256:e7399ab865399fce322f9cefc6f2f3e4099d087ba581888a9fea1bbe1db42a08",
"sha256:e7d1c280d86d72735a420610df592aac72332194e531a8beff43a592c3a1b8eb",
"sha256:e90243fee902adb0c39eceb3c69995c0f2004bc3fdb482fbf629efc656d124ed"
],
"version": "==4.3.1"
}
},
"develop": {}
}

View File

@ -0,0 +1,169 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.syncintegration
import android.os.SystemClock.sleep
import android.widget.EditText
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.replaceText
import androidx.test.espresso.action.ViewActions.pressImeActionButton
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.ui.robots.homeScreen
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
import org.hamcrest.Matchers.allOf
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.TestAssetHelper
@Suppress("RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
class SyncIntegrationTest {
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
@get:Rule
val activityTestRule = HomeActivityTestRule()
// History item Desktop -> Fenix
@Test
fun checkHistoryFromDesktopTest() {
signInFxSync()
tapReturnToPreviousApp()
homeScreen {
}.openThreeDotMenu {
}.openLibrary {
}.openHistory { }
historyAfterSyncIsShown()
}
/* These tests will be running in the future
// once the test above runs successfully and
// the environment is stable
// Bookmark item Desktop -> Fenix
@Test
fun checkBookmarkFromDesktopTest() {
signInFxSync()
tapReturnToPreviousApp()
homeScreen {
}.openThreeDotMenu {
}.openLibrary {
}.openBookmarks { }
bookmarkAfterSyncIsShown()
}
// History item Fenix -> Desktop
@Test
fun checkBookmarkFromDeviceTest() {
tapInToolBar()
typeInToolBar()
seeBookmark()
mDevice.pressBack()
signInFxSync()
}
// Bookmark item Fenix -> Desktop
@Test
fun checkHistoryFromDeviceTest() {
tapInToolBar()
typeInToolBar()
sleep(TestAssetHelper.waitingTime)
mDevice.pressBack()
signInFxSync()
}
*/
// Useful functions for the tests
fun typeEmail() {
val emailInput = mDevice.findObject(UiSelector()
.instance(0)
.className(EditText::class.java))
emailInput.waitForExists(TestAssetHelper.waitingTime)
val emailAddress = javaClass.classLoader.getResource("email.txt").readText()
emailInput.setText(emailAddress)
}
fun tapOnContinueButton() {
val continueButton = mDevice.findObject(By.res("submit-btn"))
continueButton.clickAndWait(Until.newWindow(), TestAssetHelper.waitingTime)
}
fun typePassowrd() {
val passwordInput = mDevice.findObject(UiSelector()
.instance(0)
.className(EditText::class.java))
val passwordValue = javaClass.classLoader.getResource("password.txt").readText()
passwordInput.setText(passwordValue)
}
fun tapOnSignIn() {
mDevice.wait(Until.findObjects(By.text("Sign in")), TestAssetHelper.waitingTime)
// Let's tap on enter, sometimes depending on the device the sign in button is
// hidden by the keyboard
mDevice.pressEnter()
}
fun typeInToolBar() {
awesomeBar().perform(replaceText("example.com"),
pressImeActionButton())
}
fun historyAfterSyncIsShown() {
val historyEntry = mDevice.findObject(By.text("http://www.example.com/"))
historyEntry.isEnabled()
}
fun bookmarkAfterSyncIsShown() {
val bookmarkyEntry = mDevice.findObject(By.text("Example Domain"))
bookmarkyEntry.isEnabled()
}
fun seeBookmark() {
mDevice.wait(Until.findObjects(By.text("Bookmark")), TestAssetHelper.waitingTime)
val bookmarkButton = mDevice.findObject(By.text("Bookmark"))
bookmarkButton.click()
}
fun tapReturnToPreviousApp() {
mDevice.wait(Until.findObjects(By.text("Connected")), TestAssetHelper.waitingTime)
val settingsLabel = mDevice.wait(Until.findObject(By.text("Settings")), TestAssetHelper.waitingTime)
settingsLabel.isClickable()
mDevice.wait(Until.findObjects(By.desc("Navigate up")), TestAssetHelper.waitingTime)
val backButton = mDevice.findObject(By.desc("Navigate up"))
backButton.click()
}
fun signInFxSync() {
homeScreen {
}.openThreeDotMenu {
verifySettingsButton()
}.openSettings {}
settingsAccount()
useEmailInsteadButton()
typeEmail()
tapOnContinueButton()
typePassowrd()
sleep(TestAssetHelper.waitingTime)
tapOnSignIn()
}
}
fun settingsAccount() = onView(allOf(withText("Turn on Sync"))).perform(click())
fun tapInToolBar() = onView(withId(org.mozilla.fenix.R.id.toolbar_wrapper))
fun awesomeBar() = onView(withId(org.mozilla.fenix.R.id.mozac_browser_toolbar_edit_url_view))
fun useEmailInsteadButton() = onView(withId(R.id.signInEmailButton)).perform(click())

View File

@ -0,0 +1,16 @@
import logging
import subprocess
import os
logging.getLogger(__name__).addHandler(logging.NullHandler())
class ADBrun(object):
binary = 'adbrun'
logger = logging.getLogger()
def launch(self):
# First close sim if any then launch
os.system('~/Library/Android/sdk/platform-tools/adb devices | grep emulator | cut -f1 | while read line; do ~/Library/Android/sdk/platform-tools/adb -s $line emu kill; done')
# Then launch sim
os.system("sh launchSimScript.sh")

View File

@ -0,0 +1,167 @@
import io
import json
import os
import time
from mozdownload import DirectScraper, FactoryScraper
from mozprofile import Profile
import mozinstall
import mozversion
import pytest
import requests
from tps import TPS
from gradlewbuild import GradlewBuild
here = os.path.dirname(__file__)
@pytest.fixture(scope='session')
def firefox(pytestconfig, tmpdir_factory):
binary = os.getenv('MOZREGRESSION_BINARY',
pytestconfig.getoption('firefox'))
if binary is None:
cache_dir = str(pytestconfig.cache.makedir('firefox'))
scraper = FactoryScraper('daily', destination=cache_dir)
build_path = scraper.download()
install_path = str(tmpdir_factory.mktemp('firefox'))
install_dir = mozinstall.install(src=build_path, dest=install_path)
binary = mozinstall.get_binary(install_dir, 'firefox')
version = mozversion.get_version(binary)
if hasattr(pytestconfig, '_metadata'):
pytestconfig._metadata.update(version)
return binary
@pytest.fixture
def firefox_log(pytestconfig, tmpdir):
firefox_log = str(tmpdir.join('firefox.log'))
pytestconfig._firefox_log = firefox_log
yield firefox_log
@pytest.fixture(scope='session')
def tps_addon(pytestconfig, tmpdir_factory):
path = pytestconfig.getoption('tps')
if path is not None:
return path
task_url = 'https://index.taskcluster.net/v1/task/' \
'gecko.v2.mozilla-central.latest.firefox.addons.tps'
task_id = requests.get(task_url).json().get('taskId')
cache_dir = str(pytestconfig.cache.makedir('tps-{}'.format(task_id)))
addon_url = 'https://queue.taskcluster.net/v1/task/' \
'{}/artifacts/public/tps.xpi'.format(task_id)
scraper = DirectScraper(addon_url, destination=cache_dir)
return scraper.download()
@pytest.fixture
def tps_config(fxa_account, monkeypatch):
monkeypatch.setenv('FXA_EMAIL', fxa_account.email)
monkeypatch.setenv('FXA_PASSWORD', fxa_account.password)
with open ("/Users/synctesting/.jenkins/workspace/fenix/app/src/androidTest/resources/email.txt", "w") as f:
f.write(fxa_account.email)
with open ("/Users/synctesting/.jenkins/workspace/fenix/app/src/androidTest/resources/password.txt", "w") as f:
f.write(fxa_account.password)
yield {'fx_account': {
'username': fxa_account.email,
'password': fxa_account.password}
}
@pytest.fixture
def tps_log(pytestconfig, tmpdir):
tps_log = str(tmpdir.join('tps.log'))
pytestconfig._tps_log = tps_log
yield tps_log
@pytest.fixture
def tps_profile(pytestconfig, tps_addon, tps_config, tps_log, fxa_urls):
preferences = {
'app.update.enabled': False,
'browser.dom.window.dump.enabled': True,
'browser.onboarding.enabled': False,
'browser.sessionstore.resume_from_crash': False,
'browser.shell.checkDefaultBrowser': False,
'browser.startup.homepage_override.mstone': 'ignore',
'browser.startup.page': 0,
'browser.tabs.warnOnClose': False,
'browser.warnOnQuit': False,
'datareporting.policy.dataSubmissionEnabled': False,
# 'devtools.chrome.enabled': True,
# 'devtools.debugger.remote-enabled': True,
'engine.bookmarks.repair.enabled': False,
'extensions.autoDisableScopes': 10,
'extensions.legacy.enabled': True,
'extensions.update.enabled': False,
'extensions.update.notifyUser': False,
# While this line is commented prod is launched instead of stage
'identity.fxaccounts.autoconfig.uri': fxa_urls['content'],
'testing.tps.skipPingValidation': True,
'services.sync.firstSync': 'notReady',
'services.sync.lastversion': '1.0',
'services.sync.log.appender.console': 'Trace',
'services.sync.log.appender.dump': 'Trace',
'services.sync.log.appender.file.level': 'Trace',
'services.sync.log.appender.file.logOnSuccess': True,
'services.sync.log.logger': 'Trace',
'services.sync.log.logger.engine': 'Trace',
'services.sync.testing.tps': True,
'testing.tps.logFile': tps_log,
'toolkit.startup.max_resumed_crashes': -1,
'tps.config': json.dumps(tps_config),
'tps.seconds_since_epoch': int(time.time()),
'xpinstall.signatures.required': False
}
profile = Profile(addons=[tps_addon], preferences=preferences)
pytestconfig._profile = profile.profile
yield profile
@pytest.fixture
def tps(firefox, firefox_log, monkeypatch, pytestconfig, tps_log, tps_profile):
yield TPS(firefox, firefox_log, tps_log, tps_profile)
@pytest.fixture
def gradlewbuild_log(pytestconfig, tmpdir):
gradlewbuild_log = str(tmpdir.join('gradlewbuild.log'))
pytestconfig._gradlewbuild_log = gradlewbuild_log
yield gradlewbuild_log
@pytest.fixture
def gradlewbuild(fxa_account, monkeypatch, gradlewbuild_log):
monkeypatch.setenv('FXA_EMAIL', fxa_account.email)
monkeypatch.setenv('FXA_PASSWORD', fxa_account.password)
yield GradlewBuild(gradlewbuild_log)
def pytest_addoption(parser):
parser.addoption('--firefox', help='path to firefox binary (defaults to '
'downloading latest nightly build)')
parser.addoption('--tps', help='path to tps add-on (defaults to '
'downloading latest nightly build)')
@pytest.mark.hookwrapper
def pytest_runtest_makereport(item, call):
outcome = yield
report = outcome.get_result()
extra = getattr(report, 'extra', [])
pytest_html = item.config.pluginmanager.getplugin('html')
profile = getattr(item.config, '_profile', None)
if profile is not None and os.path.exists(profile):
# add sync logs to HTML report
for root, _, files in os.walk(os.path.join(profile, 'weave', 'logs')):
for f in files:
path = os.path.join(root, f)
if pytest_html is not None:
with io.open(path, 'r', encoding='utf8') as f:
extra.append(pytest_html.extras.text(f.read(), 'Sync'))
report.sections.append(('Sync', 'Log: {}'.format(path)))
for log in ('Firefox', 'TPS', 'GradlewBuild'):
attr = '_{}_log'.format(log.lower())
path = getattr(item.config, attr, None)
if path is not None and os.path.exists(path):
if pytest_html is not None:
with io.open(path, 'r', encoding='utf8') as f:
extra.append(pytest_html.extras.text(f.read(), log))
report.sections.append((log, 'Log: {}'.format(path)))
report.extra = extra

View File

@ -0,0 +1,35 @@
import logging
import os
import subprocess
from adbrun import ADBrun
here = os.path.dirname(__file__)
logging.getLogger(__name__).addHandler(logging.NullHandler())
class GradlewBuild(object):
binary = './gradlew'
logger = logging.getLogger()
adbrun = ADBrun()
def __init__(self, log):
self.log = log
def test(self, identifier):
self.adbrun.launch()
# Change path accordingly to go to root folder to run gradlew
os.chdir('../../../../../../../..')
args = './gradlew ' + 'app:connectedGeckoNightlyDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=org.mozilla.fenix.syncintegration.SyncIntegrationTest#{}'.format(identifier)
self.logger.info('Running: {}'.format(' '.join(args)))
try:
out = subprocess.check_output(
args, shell=True)
except subprocess.CalledProcessError as e:
out = e.output
raise
finally:
with open(self.log, 'w') as f:
f.writelines(out)

View File

@ -0,0 +1,26 @@
#!/usr/bin/env bash
set -e
echo "Waiting emulator is ready..."
~/Library/Android/sdk/emulator/emulator -avd Pixel_3_API_28 -wipe-data -no-boot-anim -screen no-touch &
bootanim=""
failcounter=0
timeout_in_sec=360
until [[ "$bootanim" =~ "stopped" ]]; do
bootanim=`~/Library/Android/sdk/platform-tools/adb -e shell getprop init.svc.bootanim 2>&1 &`
if [[ "$bootanim" =~ "device not found" || "$bootanim" =~ "device offline"
|| "$bootanim" =~ "running" ]]; then
let "failcounter += 1"
echo "Waiting for emulator to start"
if [[ $failcounter -gt timeout_in_sec ]]; then
echo "Timeout ($timeout_in_sec seconds) reached; failed to start emulator"
exit 1
fi
fi
sleep 1
done
echo "Emulator is ready"
sleep 10

View File

@ -0,0 +1,4 @@
[pytest]
addopts = --verbose --html=results/index.html
log_cli = true
log_cli_level = info

View File

@ -0,0 +1,25 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* The list of phases mapped to their corresponding profiles. The object
* here must be in strict JSON format, as it will get parsed by the Python
* testrunner (no single quotes, extra comma's, etc).
*/
EnableEngines(["bookmarks"]);
var phases = { "phase1": "profile1" };
// expected bookmark state
var bookmarksExpected = {
"mobile": [{
uri: "http://www.example.com/",
title: "Example Domain"}]
};
// sync and verify bookmarks
Phase("phase1", [
[Sync],
[Bookmarks.verify, bookmarksExpected],
]);

View File

@ -0,0 +1,33 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* The list of phases mapped to their corresponding profiles. The object
* here must be in strict JSON format, as it will get parsed by the Python
* testrunner (no single quotes, extra comma's, etc).
*/
EnableEngines(["history"]);
var phases = { "phase1": "profile1" };
// expected history state
var historyCreated = [
{ uri: "http://www.example.com/",
visits: [
{ type: 1 ,
date: 0
},
{ type: 2,
date: -1
}
]
}
];
// sync and verify history
Phase("phase1", [
[Sync],
[History.add, historyCreated],
[Sync]
]);

View File

@ -0,0 +1,14 @@
import os
import sys
def test_sync_history_from_desktop(tps, gradlewbuild):
# Running tests
tps.run('test_history.js')
gradlewbuild.test('checkHistoryFromDesktopTest')
'''
# For the future, this way we change the test to run....
def test_sync_bookmark_from_device(tps, xcodebuild):
gradlewbuild.test('checkBookmarkFromDeviceTest')
tps.run('app/src/androidTest/java/org/mozilla/fenix/ui/SyncIntegrationTests/test_bookmark.js')
'''

View File

@ -0,0 +1,52 @@
import logging
import os
from mozrunner import FirefoxRunner
logging.getLogger(__name__).addHandler(logging.NullHandler())
TIMEOUT = 60
class TPS(object):
logger = logging.getLogger()
def __init__(self, firefox, firefox_log, tps_log, profile):
self.firefox = firefox
self.firefox_log = open(firefox_log, 'w')
self.tps_log = tps_log
self.profile = profile
def _log(self, line):
self.firefox_log.write(line + '\n')
def run(self, test, phase='phase1', ignore_unused_engines=True):
self.profile.set_preferences({
'testing.tps.testFile': os.path.abspath(test),
'testing.tps.testPhase': phase,
'testing.tps.ignoreUnusedEngines': ignore_unused_engines,
})
args = ['-marionette']
process_args = {'processOutputLine': [self._log]}
self.logger.info('Running: {} {}'.format(self.firefox, ' '.join(args)))
self.logger.info('Using profile at: {}'.format(self.profile.profile))
runner = FirefoxRunner(
binary=self.firefox,
cmdargs=args,
profile=self.profile,
process_args=process_args)
runner.start(timeout=TIMEOUT)
runner.wait(timeout=TIMEOUT)
self.firefox_log.close()
with open(self.tps_log) as f:
for line in f.readlines():
if 'CROSSWEAVE ERROR: ' in line:
raise TPSError(line.partition('CROSSWEAVE ERROR: ')[-1])
with open(self.tps_log) as f:
assert 'test phase {}: PASS'.format(phase) in f.read()
class TPSError(Exception):
pass

View File

View File

@ -54,34 +54,24 @@ class BackgroundServices(
historyStorage: PlacesHistoryStorage,
bookmarkStorage: PlacesBookmarksStorage
) {
companion object {
const val CLIENT_ID = "a2270f727f45f648"
fun redirectUrl(context: Context) = if (context.isInExperiment(Experiments.asFeatureWebChannelsDisabled)) {
"https://accounts.firefox.com/oauth/success/$CLIENT_ID"
} else {
"urn:ietf:wg:oauth:2.0:oob:oauth-redirect-webchannel"
}
}
// // A malformed string is causing crashes.
// This will be removed when the string is fixed. See #5552
fun defaultDeviceName(context: Context): String = try {
context.getString(
R.string.default_device_name,
context.getString(R.string.app_name),
Build.MANUFACTURER,
Build.MODEL
)
} catch (ex: FormatFlagsConversionMismatchException) {
"%s on %s %s".format(
context.getString(R.string.app_name),
Build.MANUFACTURER,
Build.MODEL
)
}
context.getString(
R.string.default_device_name,
context.getString(R.string.app_name),
Build.MANUFACTURER,
Build.MODEL
)
} catch (ex: FormatFlagsConversionMismatchException) {
"%s on %s %s".format(
context.getString(R.string.app_name),
Build.MANUFACTURER,
Build.MODEL
)
}
private val serverConfig = ServerConfig.release(CLIENT_ID, redirectUrl(context))
private val serverConfig = FxaServer.config(context)
private val deviceConfig = DeviceConfig(
name = defaultDeviceName(context),
type = DeviceType.MOBILE,

View File

@ -0,0 +1,28 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.components
import android.content.Context
import mozilla.components.service.fxa.ServerConfig
import org.mozilla.fenix.Experiments
import org.mozilla.fenix.isInExperiment
/**
* Utility to configure Firefox Account servers.
*/
object FxaServer {
const val CLIENT_ID = "a2270f727f45f648"
const val REDIRECT_URL = "https://accounts.firefox.com/oauth/success/$CLIENT_ID"
fun redirectUrl(context: Context) = if (context.isInExperiment(Experiments.asFeatureWebChannelsDisabled)) {
REDIRECT_URL
} else {
"urn:ietf:wg:oauth:2.0:oob:oauth-redirect-webchannel"
}
fun config(context: Context): ServerConfig {
return ServerConfig.release(CLIENT_ID, redirectUrl(context))
}
}

View File

@ -28,10 +28,12 @@ class Services(
private val context: Context,
private val accountManager: FxaAccountManager
) {
val fxaRedirectUrl = FxaServer.redirectUrl(context)
val accountsAuthFeature by lazy {
FirefoxAccountsAuthFeature(
accountManager,
redirectUrl = BackgroundServices.redirectUrl(context)
redirectUrl = fxaRedirectUrl
) { context, authUrl ->
CoroutineScope(Dispatchers.Main).launch {
val intent = SupportUtils.createAuthCustomTabIntent(context, authUrl)

View File

@ -105,6 +105,6 @@
<!-- Quick Action Sheet -->
<string name="pref_key_bounce_quick_action" translatable="false">pref_key_bounce_quick_action</string>
<string name="pref_key_reader_mode_notification" translatable="false">pref_key_reader_mode_notification</string>
<string name="pref_key_adjust_campaign" translatable="false">pref_key_adjust_campaign</string>
<string name="pref_key_testing_stage" translatable="false">pref_key_testing_stage</string>
</resources>

View File

@ -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", FxaServer.redirectUrl(context))
every { context.isInExperiment(eq(Experiments.asFeatureWebChannelsDisabled)) } returns true
assertEquals("https://accounts.firefox.com/oauth/success/a2270f727f45f648", BackgroundServices.redirectUrl(context))
assertEquals("https://accounts.firefox.com/oauth/success/a2270f727f45f648", FxaServer.redirectUrl(context))
every { context.isInExperiment(eq(Experiments.asFeatureSyncDisabled)) } returns false
var backgroundServices = TestableBackgroundServices(context)

View File

@ -37,6 +37,9 @@ gcloud:
- /sdcard/screenshots
performance-metrics: true
test-targets:
- package org.mozilla.fenix.ui
device:
- model: Nexus6
version: 25

View File

@ -0,0 +1,26 @@
### Sync Integration Tests
The aim of these tests is to check that the synchronization is working between Fenix and Desktop. The intention is to add tests for History, Bookmarks, Tabs and Logins.
At this moment only tests for History and Bookmarks are defined.
### Steps to Run
To run these tests you will need Python 2 and pipenv installed. Once you have these, make sure you're in the `syncintegration` directory and run the following:
`$ pipenv install`
`$ pipenv run pytest`
When a test is launched a stage account is created. That will be used both in Desktop and Fenix to be sure that what is saved in one place is shown in the other.
The process for example for History item Desktop -> Fenix, would be:
- Desktop is launched, user signed in and history item created.
- Android sim is launched (Pixel 3 API28), Fenix app starts and same user is signed in, then we go to History list and verify that the item is there.
### Results
Due to the set up necessary these tests do not run as part of the regular CI, via Taskcluster.
The idea is to have them running on Jenkins periodically (TBD how often).
Once they finish there is a slack notificattion received informing about the result (so far that is configured for #firefox-ios-alerts)
A html file is generated with all the info, for each step to make it easy to debug in case of failure.
## Notes
More detailed info can be found [`here`](https://docs.google.com/document/d/1dhxlbGQBA6aJi2Xz-CsJZuGJPRReoL7nfm9cYu4HcZI/edit?usp=sharing)