diff --git a/espresso-server/library/src/main/java/io/appium/espressoserver/lib/handlers/Status.kt b/espresso-server/library/src/main/java/io/appium/espressoserver/lib/handlers/Status.kt index 1dd411e8..bf5bd5b3 100644 --- a/espresso-server/library/src/main/java/io/appium/espressoserver/lib/handlers/Status.kt +++ b/espresso-server/library/src/main/java/io/appium/espressoserver/lib/handlers/Status.kt @@ -16,11 +16,22 @@ package io.appium.espressoserver.lib.handlers +import androidx.test.platform.app.InstrumentationRegistry +import io.appium.espressoserver.lib.helpers.getEspressoServerVersion import io.appium.espressoserver.lib.model.AppiumParams +import io.appium.espressoserver.lib.model.BuildInfo -class Status : RequestHandler, NoSessionCommandHandler { - override fun handleInternal(params: AppiumParams): Void? { - return null +class Status : RequestHandler, NoSessionCommandHandler { + + override fun handleInternal(params: AppiumParams): io.appium.espressoserver.lib.model.Status { + return io.appium.espressoserver.lib.model.Status( + ready = true, + message = "The server is ready to accept new connections", + build = BuildInfo( + version = getEspressoServerVersion(), + packageName = InstrumentationRegistry.getInstrumentation().targetContext.packageName + ) + ) } } diff --git a/espresso-server/library/src/main/java/io/appium/espressoserver/lib/helpers/Version.kt b/espresso-server/library/src/main/java/io/appium/espressoserver/lib/helpers/Version.kt new file mode 100644 index 00000000..bdc62215 --- /dev/null +++ b/espresso-server/library/src/main/java/io/appium/espressoserver/lib/helpers/Version.kt @@ -0,0 +1,7 @@ +package io.appium.espressoserver.lib.helpers + +// This value is updated automatically by the NPM versioning script +// It should be in sync with the NPM module version from package.json +private const val VERSION = "3.1.0" + +fun getEspressoServerVersion() = VERSION diff --git a/espresso-server/library/src/main/java/io/appium/espressoserver/lib/http/Router.kt b/espresso-server/library/src/main/java/io/appium/espressoserver/lib/http/Router.kt index a63f9335..f67a323b 100644 --- a/espresso-server/library/src/main/java/io/appium/espressoserver/lib/http/Router.kt +++ b/espresso-server/library/src/main/java/io/appium/espressoserver/lib/http/Router.kt @@ -21,6 +21,7 @@ import com.google.gson.JsonParseException import fi.iki.elonen.NanoHTTPD.Method import io.appium.espressoserver.lib.handlers.* import io.appium.espressoserver.lib.handlers.PointerEventHandler.TouchType.* +import io.appium.espressoserver.lib.handlers.Status import io.appium.espressoserver.lib.handlers.TouchAction import io.appium.espressoserver.lib.handlers.exceptions.* import io.appium.espressoserver.lib.helpers.AndroidLogger diff --git a/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/AppiumParams.kt b/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/AppiumParams.kt index 00b43466..17e6516f 100644 --- a/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/AppiumParams.kt +++ b/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/AppiumParams.kt @@ -16,6 +16,7 @@ package io.appium.espressoserver.lib.model +import com.google.gson.annotations.Expose import io.appium.espressoserver.lib.handlers.exceptions.AppiumException @@ -23,7 +24,8 @@ const val SESSION_ID_PARAM_NAME = "sessionId" const val ELEMENT_ID_PARAM_NAME = "elementId" open class AppiumParams { - var uriParams:MutableMap? = null + @Expose(serialize = false, deserialize = true) + private var uriParams: MutableMap? = null val sessionId: String? get() = getUriParameterValue(SESSION_ID_PARAM_NAME) diff --git a/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/Location.kt b/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/Location.kt index 7a8ac70a..5d1a4660 100644 --- a/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/Location.kt +++ b/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/Location.kt @@ -16,4 +16,7 @@ package io.appium.espressoserver.lib.model -data class Location(var x: Int? = null, var y: Int? = null) : AppiumParams() +data class Location( + val x: Int, + val y: Int +) diff --git a/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/Rect.kt b/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/Rect.kt index 8aad9d99..0456c7d2 100644 --- a/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/Rect.kt +++ b/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/Rect.kt @@ -18,12 +18,12 @@ package io.appium.espressoserver.lib.model import android.graphics.Rect -class Rect( - var x: Int? = null, - var y: Int? = null, - var width: Int? = null, - var height: Int? = null -) : AppiumParams() { +data class Rect( + var x: Int, + var y: Int, + var width: Int, + var height: Int +) { companion object { fun fromBounds(bounds: Rect): io.appium.espressoserver.lib.model.Rect = io.appium.espressoserver.lib.model.Rect( diff --git a/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/Size.kt b/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/Size.kt index fbb68733..c94cce80 100644 --- a/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/Size.kt +++ b/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/Size.kt @@ -19,4 +19,4 @@ package io.appium.espressoserver.lib.model data class Size( val width: Int, val height: Int -) : AppiumParams() \ No newline at end of file +) \ No newline at end of file diff --git a/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/Status.kt b/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/Status.kt new file mode 100644 index 00000000..5681ac22 --- /dev/null +++ b/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/Status.kt @@ -0,0 +1,28 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.appium.espressoserver.lib.model + +data class Status( + val ready: Boolean, + val message: String, + val build: BuildInfo +) + +data class BuildInfo( + val version: String, + val packageName: String +) diff --git a/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/WindowRect.kt b/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/WindowRect.kt index a160477e..1b6cc823 100644 --- a/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/WindowRect.kt +++ b/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/WindowRect.kt @@ -21,4 +21,4 @@ data class WindowRect( val height: Int, val x: Int, val y: Int -) : AppiumParams() +) diff --git a/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/WindowSize.kt b/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/WindowSize.kt index 3ed915ff..172c8ba5 100644 --- a/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/WindowSize.kt +++ b/espresso-server/library/src/main/java/io/appium/espressoserver/lib/model/WindowSize.kt @@ -19,4 +19,4 @@ package io.appium.espressoserver.lib.model data class WindowSize( val width: Int, val height: Int -) : AppiumParams() +) diff --git a/package.json b/package.json index a5f17086..0b2750ba 100644 --- a/package.json +++ b/package.json @@ -98,9 +98,11 @@ "lint:server": "cd espresso-server && ./gradlew lint || cd ..", "lint:fix": "npm run lint -- --fix", "prepare": "npm run rebuild", + "sync-version": "node ./scripts/sync-version.js --package-version=${npm_package_version}", "test": "npm run test:node", "test:node": "mocha --exit --timeout 1m \"./test/unit/**/*-specs.js\"", "test:server": "cd espresso-server && ./gradlew test --stacktrace || cd ..", + "version": "npm run sync-version && npm run build:server", "e2e-test": "mocha --exit --timeout 5m \"./test/functional/**/*-specs.js\"" }, "peerDependencies": { @@ -130,6 +132,7 @@ "rimraf": "^5.0.0", "semantic-release": "^24.0.0", "sinon": "^17.0.0", + "semver": "^7.3.7", "ts-node": "^10.9.1", "typescript": "^5.4.2", "webdriverio": "^8.0.2", diff --git a/scripts/sync-version.js b/scripts/sync-version.js new file mode 100644 index 00000000..5ccb09ae --- /dev/null +++ b/scripts/sync-version.js @@ -0,0 +1,47 @@ +const path = require('node:path'); +const { logger, fs } = require('appium/support'); +const semver = require('semver'); + +const LOG = logger.getLogger('VersionSync'); + +const ROOT_DIR = path.resolve(__dirname, '..'); +const ESPRESSO_SERVER_ROOT = path.join(ROOT_DIR, 'espresso-server'); +const VERSION_FILE = path.join( + ESPRESSO_SERVER_ROOT, 'library', 'src', 'main', 'java', + 'io', 'appium', 'espressoserver', + 'lib', 'helpers', 'Version.kt' +); +const VERSION_PATTERN = /VERSION\s*=\s*"([0-9.]+)"/; + +function parseArgValue (argName) { + const argNamePattern = new RegExp(`^--${argName}\\b`); + for (let i = 1; i < process.argv.length; ++i) { + const arg = process.argv[i]; + if (argNamePattern.test(arg)) { + return arg.includes('=') ? arg.split('=')[1] : process.argv[i + 1]; + } + } + return null; +} + +async function syncModuleVersion () { + const origContent = await fs.readFile(VERSION_FILE, 'utf8'); + const espressoVersionMatch = VERSION_PATTERN.exec(origContent); + if (!espressoVersionMatch) { + throw new Error(`Could not parse Espresso module version from '${VERSION_FILE}'`); + } + const packageVersion = parseArgValue('package-version'); + if (!packageVersion) { + throw new Error('No package version argument (use `--package-version=xxx`)'); + } + if (!semver.valid(packageVersion)) { + throw new Error( + `Invalid version specified '${packageVersion}'. Version should be in the form '1.2.3'` + ); + } + const updatedContent = origContent.replace(espressoVersionMatch[1], packageVersion); + await fs.writeFile(VERSION_FILE, updatedContent, 'utf8'); + LOG.info(`Synchronized module version '${packageVersion}' to '${VERSION_FILE}'`); +} + +(async () => await syncModuleVersion())();