diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ac31227..ec9ead7 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -11,17 +11,17 @@ on:
jobs:
test-ios:
name: "iOS Tests"
- runs-on: macos-12
+ runs-on: macos-14
env:
- DEVELOPER_DIR: /Applications/Xcode_13.4.1.app/Contents/Developer
+ DEVELOPER_DIR: /Applications/Xcode_15.4.app/Contents/Developer
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Use Node.js
- uses: actions/setup-node@v3
+ uses: actions/setup-node@v4
with:
- node-version: 16
+ node-version: 20
- name: Set up example app
run: |
@@ -35,14 +35,63 @@ jobs:
-project OAuthPluginTests.xcodeproj \
-scheme OAuthPluginTests \
-testPlan UnitTests \
- -destination "platform=iOS Simulator,name=iPhone 13"
+ -destination "platform=iOS Simulator,name=iPhone 15"
working-directory: ./tests/ios
- name: Run iOS UI Tests
run: |
- xcodebuild test -quiet \
+ xcodebuild test \
-project OAuthPluginTests.xcodeproj \
-scheme OAuthPluginTests \
-testPlan DeviceTests \
- -destination "platform=iOS Simulator,name=iPhone 13"
+ -destination "platform=iOS Simulator,name=iPhone 15" \
+ -destination-timeout 300
working-directory: ./tests/ios
+
+
+ test-android:
+ name: "Android Tests"
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Enable KVM group perms
+ run: |
+ echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
+ sudo udevadm control --reload-rules
+ sudo udevadm trigger --name-match=kvm
+
+ - uses: actions/checkout@v4
+
+ - name: Use Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: 20
+
+ - name: Use Java
+ uses: actions/setup-java@v4
+ with:
+ distribution: temurin
+ java-version: 17
+
+ - name: Set up example app
+ run: |
+ npm i
+ npx cordova prepare android
+ working-directory: ./example
+
+ - name: Set up gradle
+ uses: gradle/actions/setup-gradle@v3
+ with:
+ gradle-version: 8.4
+
+ - name: Run Android Unit Tests
+ run: |
+ gradle test
+ working-directory: ./tests/android
+
+ - name: Run Android UI Tests
+ uses: reactivecircus/android-emulator-runner@v2
+ with:
+ api-level: 29
+ script: gradle connectedCheck
+ working-directory: ./tests/android
diff --git a/src/android/OAuthPlugin.java b/src/android/OAuthPlugin.java
index 830d0f8..0b05b88 100644
--- a/src/android/OAuthPlugin.java
+++ b/src/android/OAuthPlugin.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2019 Ayogo Health Inc.
+ * Copyright 2019 - 2022 Ayogo Health Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,20 +16,12 @@
package com.ayogo.cordova.oauth;
-import android.app.Activity;
-import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import android.net.Uri;
import androidx.browser.customtabs.CustomTabsIntent;
-import android.text.TextUtils;
-
-import java.util.ArrayList;
-import java.util.List;
import org.apache.cordova.CallbackContext;
+import org.apache.cordova.CordovaArgs;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView;
@@ -37,7 +29,6 @@
import org.apache.cordova.LOG;
import org.apache.cordova.PluginResult;
-import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -45,22 +36,6 @@
public class OAuthPlugin extends CordovaPlugin {
private final String TAG = "OAuthPlugin";
- // Taken from Google's CustomTabsHelper
- // https://github.com/GoogleChrome/custom-tabs-client/blob/da65829d7d4b80c00809c6c4aa7f61f88fc7ca26/shared/src/main/java/org/chromium/customtabsclient/shared/CustomTabsHelper.java
- static final String STABLE_PACKAGE = "com.android.chrome";
- static final String BETA_PACKAGE = "com.chrome.beta";
- static final String DEV_PACKAGE = "com.chrome.dev";
- static final String LOCAL_PACKAGE = "com.google.android.apps.chrome";
- private static final String EXTRA_CUSTOM_TABS_KEEP_ALIVE = "android.support.customtabs.extra.KEEP_ALIVE";
- private static final String ACTION_CUSTOM_TABS_CONNECTION = "android.support.customtabs.action.CustomTabsService";
-
-
- /**
- * The name of the package to use for the custom tab service.
- */
- private String tabProvider = null;
-
-
/**
* Executes the request.
*
@@ -76,7 +51,7 @@ public class OAuthPlugin extends CordovaPlugin {
* @return Whether the action was valid.
*/
@Override
- public boolean execute(String action, JSONArray args, CallbackContext callbackContext) {
+ public boolean execute(String action, CordovaArgs args, CallbackContext callbackContext) {
if ("startOAuth".equals(action)) {
try {
String authEndpoint = args.getString(0);
@@ -121,15 +96,7 @@ public void onNewIntent(Intent intent) {
jsobj.put(queryKey, uri.getQueryParameter(queryKey));
}
- final String msg = jsobj.toString();
- CordovaWebViewEngine engine = this.webView.getEngine();
- final String jsCode = "window.dispatchEvent(new MessageEvent('message', { data: 'oauth::" + msg + "' }));";
- if (engine != null) {
- engine.evaluateJavascript(jsCode, null);
- } else {
- this.webView.sendJavascript(jsCode);
- }
-
+ dispatchOAuthMessage(jsobj.toString());
} catch (JSONException e) {
LOG.e(TAG, "JSON Serialization failed");
e.printStackTrace();
@@ -144,112 +111,20 @@ public void onNewIntent(Intent intent) {
* @param url The URL of the OAuth endpoint.
*/
private void startOAuth(String url) {
- String customTabsBrowser = findCustomTabProvider();
-
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
CustomTabsIntent customTabsIntent = builder.build();
-
- String packageName = this.findCustomTabProvider();
- if (packageName != null) {
- customTabsIntent.intent.setPackage(packageName);
- }
-
customTabsIntent.launchUrl(this.cordova.getActivity(), Uri.parse(url));
}
+ @SuppressWarnings("deprecation")
+ private void dispatchOAuthMessage(final String msg) {
+ final String jsCode = "window.dispatchEvent(new MessageEvent('message', { data: 'oauth::" + msg + "' }));";
- /**
- * Goes through all apps that handle VIEW intents and have a warmup service.
- *
- * Picks the one chosen by the user if there is one, otherwise makes a best
- * effort to return a valid package name.
- *
- * This is not threadsafe.
- *
- * @return The package name recommended to use for connecting to custom
- * tabs related components.
- */
- private String findCustomTabProvider() {
- if (this.tabProvider != null) {
- return this.tabProvider;
- }
-
- PackageManager pm = this.cordova.getActivity().getPackageManager();
-
- // Get default VIEW intent handler.
- Intent activityIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.example.com"));
- ResolveInfo defaultViewHandlerInfo = pm.resolveActivity(activityIntent, 0);
- String defaultViewHandlerPackageName = null;
-
- if (defaultViewHandlerInfo != null) {
- defaultViewHandlerPackageName = defaultViewHandlerInfo.activityInfo.packageName;
+ CordovaWebViewEngine engine = this.webView.getEngine();
+ if (engine != null) {
+ engine.evaluateJavascript(jsCode, null);
+ } else {
+ this.webView.sendJavascript(jsCode);
}
-
-
- // Get all apps that can handle VIEW intents.
- List resolvedActivityList = pm.queryIntentActivities(activityIntent, PackageManager.MATCH_ALL);
- List packagesSupportingCustomTabs = new ArrayList<>();
-
- for (ResolveInfo info : resolvedActivityList) {
- Intent serviceIntent = new Intent();
- serviceIntent.setAction(ACTION_CUSTOM_TABS_CONNECTION);
- serviceIntent.setPackage(info.activityInfo.packageName);
-
- if (pm.resolveService(serviceIntent, 0) != null) {
- packagesSupportingCustomTabs.add(info.activityInfo.packageName);
- }
- }
-
- // Now packagesSupportingCustomTabs contains all apps that can handle both VIEW intents
- // and service calls.
- if (packagesSupportingCustomTabs.isEmpty()) {
- this.tabProvider = null;
- } else if (packagesSupportingCustomTabs.size() == 1) {
- this.tabProvider = packagesSupportingCustomTabs.get(0);
- } else if (!TextUtils.isEmpty(defaultViewHandlerPackageName) && !this.hasSpecializedHandlerIntents(activityIntent) && packagesSupportingCustomTabs.contains(defaultViewHandlerPackageName)) {
- this.tabProvider = defaultViewHandlerPackageName;
- } else if (packagesSupportingCustomTabs.contains(STABLE_PACKAGE)) {
- this.tabProvider = STABLE_PACKAGE;
- } else if (packagesSupportingCustomTabs.contains(BETA_PACKAGE)) {
- this.tabProvider = BETA_PACKAGE;
- } else if (packagesSupportingCustomTabs.contains(DEV_PACKAGE)) {
- this.tabProvider = DEV_PACKAGE;
- } else if (packagesSupportingCustomTabs.contains(LOCAL_PACKAGE)) {
- this.tabProvider = LOCAL_PACKAGE;
- }
-
- return this.tabProvider;
- }
-
-
- /**
- * Used to check whether there is a specialized handler for a given intent.
- *
- * @param intent The intent to check with.
- * @return Whether there is a specialized handler for the given intent.
- */
- private boolean hasSpecializedHandlerIntents(Intent intent) {
- try {
- PackageManager pm = this.cordova.getActivity().getPackageManager();
- List handlers = pm.queryIntentActivities(intent, PackageManager.GET_RESOLVED_FILTER);
-
- if (handlers == null || handlers.size() == 0) {
- return false;
- }
-
- for (ResolveInfo resolveInfo : handlers) {
- IntentFilter filter = resolveInfo.filter;
-
- if (filter == null || filter.countDataAuthorities() == 0 || filter.countDataPaths() == 0 || resolveInfo.activityInfo == null) {
- continue;
- }
-
- return true;
- }
- } catch (RuntimeException e) {
- LOG.e(TAG, "Runtime exception while getting specialized handlers");
- }
-
- return false;
}
}
diff --git a/tests/android/.gitignore b/tests/android/.gitignore
new file mode 100644
index 0000000..6b382aa
--- /dev/null
+++ b/tests/android/.gitignore
@@ -0,0 +1,5 @@
+build/
+.gradle/
+src/main/java/com/ayogo/cordova/oauth/OAuthPlugin.java
+src/main/assets/
+src/main/res/
diff --git a/tests/android/build.gradle b/tests/android/build.gradle
new file mode 100644
index 0000000..4f5d2ae
--- /dev/null
+++ b/tests/android/build.gradle
@@ -0,0 +1,91 @@
+/**
+ * Copyright 2022 Ayogo Health Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://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.
+ */
+
+buildscript {
+ repositories {
+ google()
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:8.3.1'
+ }
+}
+
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 34
+
+ defaultConfig {
+ namespace 'com.ayogo.cordova.oauth.tests'
+ applicationId 'com.ayogo.cordova.oauth.tests'
+ minSdkVersion 24
+ targetSdkVersion 34
+ versionCode 1
+ versionName '1.0'
+ testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
+ }
+
+ buildTypes {
+ debug {
+ testCoverageEnabled true
+ }
+ }
+}
+
+repositories {
+ google()
+ mavenCentral()
+}
+
+dependencies {
+ // These should get pulled in by the Cordova package, but don't :(
+ implementation 'androidx.appcompat:appcompat:[1.4.2,)'
+ implementation 'androidx.core:core-splashscreen:[1.0.0,)'
+ implementation 'androidx.webkit:webkit:[1.4.0,)'
+
+ implementation 'org.apache.cordova:framework:[11.0.0,)'
+ implementation 'androidx.browser:browser:[1.3.0,)'
+
+ testImplementation 'junit:junit:4.13.1'
+ testImplementation 'org.mockito:mockito-inline:4.6.1'
+ testImplementation 'org.json:json:[20220924,)'
+
+ androidTestImplementation 'androidx.test:core:1.5.0'
+ androidTestImplementation 'androidx.test:runner:1.5.2'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.5'
+ androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
+}
+
+task copyPluginSource(type: Copy) {
+ from '../../src/android'
+ into 'src/main/java/com/ayogo/cordova/oauth'
+}
+
+task copyExampleAssets(type: Copy) {
+ from '../../example/platforms/android/app/src/main/assets'
+ into 'src/main/assets'
+}
+
+task copyExampleResources(type: Copy) {
+ from '../../example/platforms/android/app/src/main/res'
+ into 'src/main/res'
+}
+
+preBuild.dependsOn(copyPluginSource)
+preBuild.dependsOn(copyExampleAssets)
+preBuild.dependsOn(copyExampleResources)
diff --git a/tests/android/gradle.properties b/tests/android/gradle.properties
new file mode 100644
index 0000000..d7ba8f4
--- /dev/null
+++ b/tests/android/gradle.properties
@@ -0,0 +1 @@
+android.useAndroidX = true
diff --git a/tests/android/src/androidTest/AndroidManifest.xml b/tests/android/src/androidTest/AndroidManifest.xml
new file mode 100644
index 0000000..00e4b9b
--- /dev/null
+++ b/tests/android/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
diff --git a/tests/android/src/androidTest/java/com/ayogo/cordova/oauth/OAuthPluginTest.java b/tests/android/src/androidTest/java/com/ayogo/cordova/oauth/OAuthPluginTest.java
new file mode 100644
index 0000000..d4b1fbc
--- /dev/null
+++ b/tests/android/src/androidTest/java/com/ayogo/cordova/oauth/OAuthPluginTest.java
@@ -0,0 +1,100 @@
+/**
+ * Copyright 2022 Ayogo Health Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://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 com.ayogo.cordova.oauth;
+
+import static org.junit.Assert.assertNotNull;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.webkit.WebView;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObjectNotFoundException;
+import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.Until;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class OAuthPluginTest {
+ static final long TIMEOUT = 5000;
+ static final String TEST_PACKAGE = "com.ayogo.cordova.oauth.tests";
+
+ private UiDevice device;
+
+ @Before
+ public void waitForAppLaunch() {
+ device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+
+ device.pressHome();
+
+ final String launcherPackage = getLauncherPackageName();
+ assertNotNull(launcherPackage);
+ device.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), TIMEOUT);
+
+ Context context = ApplicationProvider.getApplicationContext();
+ final Intent intent = context.getPackageManager().getLaunchIntentForPackage(TEST_PACKAGE);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ context.startActivity(intent);
+
+ device.wait(Until.hasObject(By.pkg(TEST_PACKAGE).depth(0)), TIMEOUT);
+ }
+
+ @Test
+ public void testOAuthFlow() {
+ assertNotNull(device);
+
+ device.wait(Until.findObject(By.clazz(WebView.class)), TIMEOUT);
+
+ UiObject2 loginBtn = device.wait(Until.findObject(By.text("Sign in with OAuth")), TIMEOUT);
+ assertNotNull(loginBtn);
+ loginBtn.click();
+
+ // Now we have to interact with the Chrome Custom Tab
+ UiObject2 oauthBtn = device.wait(Until.findObject(By.text("Click Here to Login")), TIMEOUT);
+ assertNotNull(oauthBtn);
+ oauthBtn.click();
+
+ // Should be back in the app now
+ device.wait(Until.findObject(By.clazz(WebView.class)), TIMEOUT);
+
+ device.wait(Until.findObject(By.text("LOGGED IN")), TIMEOUT);
+ }
+
+ /**
+ * Uses package manager to find the package name of the device launcher. Usually this package
+ * is "com.android.launcher" but can be different at times. This is a generic solution which
+ * works on all platforms.`
+ */
+ @SuppressWarnings("deprecation")
+ private String getLauncherPackageName() {
+ // Create launcher Intent
+ final Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.addCategory(Intent.CATEGORY_HOME);
+
+ // Use PackageManager to get the launcher package name
+ PackageManager pm = ApplicationProvider.getApplicationContext().getPackageManager();
+ ResolveInfo resolveInfo = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ return resolveInfo.activityInfo.packageName;
+ }
+}
diff --git a/tests/android/src/main/AndroidManifest.xml b/tests/android/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..114fee5
--- /dev/null
+++ b/tests/android/src/main/AndroidManifest.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/android/src/main/java/com/ayogo/cordova/oauth/tests/MainActivity.java b/tests/android/src/main/java/com/ayogo/cordova/oauth/tests/MainActivity.java
new file mode 100644
index 0000000..f1b5d06
--- /dev/null
+++ b/tests/android/src/main/java/com/ayogo/cordova/oauth/tests/MainActivity.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright 2022 Ayogo Health Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://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 com.ayogo.cordova.oauth.tests;
+
+import android.os.Bundle;
+import org.apache.cordova.CordovaActivity;
+
+public class MainActivity extends CordovaActivity {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ loadUrl(launchUrl);
+ }
+}
diff --git a/tests/android/src/test/java/com/ayogo/cordova/oauth/OAuthPluginUnitTest.java b/tests/android/src/test/java/com/ayogo/cordova/oauth/OAuthPluginUnitTest.java
new file mode 100644
index 0000000..b5f86aa
--- /dev/null
+++ b/tests/android/src/test/java/com/ayogo/cordova/oauth/OAuthPluginUnitTest.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright 2022 Ayogo Health Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://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 com.ayogo.cordova.oauth;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import org.apache.cordova.CallbackContext;
+import org.apache.cordova.CordovaArgs;
+import org.apache.cordova.PluginResult;
+import org.json.JSONException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class OAuthPluginUnitTest {
+ @Test
+ public void executeWithUnknownAction() throws JSONException {
+ OAuthPlugin plugin = new OAuthPlugin();
+
+ CallbackContext context = mock(CallbackContext.class);
+ boolean retVal = plugin.execute("unknownAction", "[]", context);
+ assertEquals(false, retVal);
+
+ ArgumentCaptor result = ArgumentCaptor.forClass(PluginResult.class);
+ verify(context).sendPluginResult(result.capture());
+ assertEquals(PluginResult.Status.INVALID_ACTION.ordinal(), result.getValue().getStatus());
+ }
+
+ @Test
+ public void executeOAuthWithMissingArgument() throws JSONException {
+ OAuthPlugin plugin = new OAuthPlugin();
+
+ CallbackContext context = mock(CallbackContext.class);
+ boolean retVal = plugin.execute("startOAuth", "[]", context);
+ assertEquals(false, retVal);
+
+ ArgumentCaptor result = ArgumentCaptor.forClass(PluginResult.class);
+ verify(context).sendPluginResult(result.capture());
+ assertEquals(PluginResult.Status.ERROR.ordinal(), result.getValue().getStatus());
+ }
+}
diff --git a/tests/ios/Tests/Tests.swift b/tests/ios/Tests/Tests.swift
index d9c6d82..38321e5 100644
--- a/tests/ios/Tests/Tests.swift
+++ b/tests/ios/Tests/Tests.swift
@@ -118,7 +118,7 @@ class OAuthPluginTests: XCTestCase {
func testOAuthCommandURL() throws {
plugin.pluginInitialize()
- let nonURLcmd = CDVInvokedUrlCommand(arguments:["Hello world!"], callbackId:"", className:"CDVOAuthPlugin", methodName:"startOAuth")
+ let nonURLcmd = CDVInvokedUrlCommand(arguments:[""], callbackId:"", className:"CDVOAuthPlugin", methodName:"startOAuth")
plugin.startOAuth(nonURLcmd!)
XCTAssertEqual(cmdDlg.lastResult.status as! UInt, CDVCommandStatus.error.rawValue)
}
diff --git a/tests/ios/UITests/UITests.swift b/tests/ios/UITests/UITests.swift
index ed6050f..00c9dd7 100644
--- a/tests/ios/UITests/UITests.swift
+++ b/tests/ios/UITests/UITests.swift
@@ -59,7 +59,7 @@ class OAuthPluginUITests: XCTestCase {
// Verify the app received the OAuth token and considers us logged in
let loggedIn = app.staticTexts["LOGGED IN"]
- _ = loggedIn.waitForExistence(timeout: 5)
+ _ = loggedIn.waitForExistence(timeout: 45)
XCTAssert(loggedIn.exists)
}
@@ -71,7 +71,7 @@ class OAuthPluginUITests: XCTestCase {
}
let oauthButton = app.webViews.buttons["Click Here to Login"]
- _ = oauthButton.waitForExistence(timeout: 5)
+ _ = oauthButton.waitForExistence(timeout: 25)
XCTAssert(oauthButton.exists)
XCTAssert(oauthButton.isHittable)
oauthButton.tap()