Android Espresso: How do I inspect elements inside a web view? - android

In the app is a Checkout.com 3DS screen and when I use Layout Inspector (Android Studio), I only see the web view but it has no subtrees. Do I need to use separate software to inspect elements in chrome web view?
I believe I have the correct code to interact with the elements but I'm just guessing the attributes at the moment and not having much luck. Using text/placeholder hasn't worked so far.
private val webView = withId(R.id.verifyByThreeDsWebView)
override fun isDisplayed() {
support.waitForViewDisplayed(webView, 20000)
}
fun enterPassword(password: String = "Checkout1!") {
onWebView(webView).forceJavascriptEnabled()
.withElement(findElement(Locator.XPATH,"//*[#placeholder='Hint: Checkout1!']"))
.perform(webKeys(password))
}
fun clickSubmit() {
onWebView(webView)
.withElement(findElement(Locator.XPATH,"\"//button[contains(text(),'Continue')]\""))
.perform(webClick())
}

Related

How to fix error when displaying Native Template Ads?

I use Native Templates: https://developers.google.com/admob/android/native/templates Everything works, but if I use app:gnt_template_type="#layout/gnt_small_template_view" Somewhere once in thirty an error pops up like on screenshots:
Although there is no MediaView in gnt_small_template_view at all. The questions are as follows:
Is it possible to leave it as it is, since this is a Google module or Google will swear?
Since this is a Google module, can I change the appearance of this View? It means again, will Google swear?
Is it generally possible to make a View for NativeAds without a MediaView? If possible, I would just make an analogue as in the module (Native Templates) but from the Native Advanced example: https://developers.google.com/admob/android/native/advanced
What else I don’t like, the module, although downloaded from official site lags behind the library version of the current com.google.android.gms:play-services-ads:21.2.0 and requires the com.google.firebase:firebase-crashlytics-buildtools:2.9.2 module to be added to Gradle, otherwise it will not compile, which also leads to the question, will Google have problems with this later?
Code:
<com.google.android.ads.nativetemplates.TemplateView
android:id="#+id/my_template"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:layout_marginBottom="32dp"
app:gnt_template_type="#layout/gnt_small_template_view" />
And in fragment in onCreateView:
private fun initNativeTemplate(view: ConstraintLayout) {
val template = view.findViewById<TemplateView>(R.id.my_template)
val adLoader: AdLoader = AdLoader.Builder(requireActivity(), "/6499/example/native").withAdListener(object :
AdListener() {
override fun onAdFailedToLoad(loadAdError: LoadAdError) {
super.onAdFailedToLoad()
Log.i("NativeAds", "onAdFailedToLoad")
}
override fun onAdLoaded() {
super.onAdLoaded()
Log.i("NativeAds", "onAdLoaded")
}
}).forNativeAd { nativeAd ->
val styles = NativeTemplateStyle.Builder().build()
template.setStyles(styles)
template.setNativeAd(nativeAd)
}.build()
adLoader.loadAd(AdRequest.Builder().build())
}

Maintaining state through screen rotation in Kotlin

There's really no code snippet for this. I'm building an Android app in Android Studio in Kotlin with a main activity in both default portrait and lanscape modes. I'm using Android Studio auto-generated layout\activity_main.xml and layout-land\activity_main.xml layouts.
PROBLEM: When I rotate screens in the app, all widgets reset state. For example, I have a TextView, tvTitle, with a default hardcoded string, "Hello World". tvTitle normally changed to "News" while using the app in portrait mode. I then switched to landscape mode and tvTitle reverted to it's hardcoded default string, Hello. How can I retain the state of the app through rotations?
You might find the solution to your particular problem after understanding the Android mechanisms for saving the application state.
I suggest that you check out the official guide.
Got it. The simple answer that works for me here is:
class MainActivity : AppCompatActivity() {
private var SavedVar = "Hello"
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString("SavedVar_KEY" ,SavedVar)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if(savedInstanceState != null) {
SavedVar = savedInstanceState.getString("SavedVar_KEY")
}
...
...
}

Android AccessibilityService: AccessibilityNodeInfo.ACTION_SET_SELECTION not working properly with multiline fields in Browser apps

I'm working on an app with intense usage of AccessibilityService. The app works great with other Android apps, I can use text selection properly.
The problem comes with multiline fields in browsers: when trying to perform the action AccessibilityNodeInfo.ACTION_SET_SELECTION, it results in a wrong selection.
Here's my example code snippet. It may not be functional, but it helps with stating the issue:
override fun onAccessibilityEvent(event: AccessibilityEvent) {
val nodeInfo = event.source
if (AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED == event.eventType
|| (AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED == event.eventType
&& event.contentChangeTypes and AccessibilityEvent.CONTENT_CHANGE_TYPE_TEXT == AccessibilityEvent.CONTENT_CHANGE_TYPE_TEXT)) {
nodeInfo?.text?.let {
val arguments = Bundle()
arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 20)
arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 20)
event.source.performAction(AccessibilityNodeInfo.ACTION_SET_SELECTION, arguments)
}
}
}
As an example of what is happening, when in https://translate.google.com/, if you write:
selection is
not
working
and after writing this text you run the code, after performing the action the caret should be placed somewhere here:
selection is
not
work|ing
but instead, it is placed here:
sel|ection is
not
working
The problem seems to be related to endlines. Everything works great if you just write and select in a single line, but when using multiline, it's not working properly.
Any clue??? Did someone experience the same issue?

Android webview request stuck in pending forever

I am showing a programmatically created webview in a bottomsheet fragment. The webview is persisted on a singleton that outlives the fragment
The webview is created like so:
webView = WebView(context).let { webView ->
webView.layoutParams = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
)
webView.clearCache(true)
WebView.setWebContentsDebuggingEnabled(BuildConfig.DEBUG)
webView.settings.javaScriptEnabled = true
webView.settings.domStorageEnabled = true
webView.measure(100, 100)
webView.settings.useWideViewPort = true
webView.settings.loadWithOverviewMode = true
webView.addJavascriptInterface(AndroidJavascriptInterface(environment), webViewHook)
webView.webViewClient = webViewClient
webView.webChromeClient = webViewChromeClient
webView.loadUrl("file:///android_asset/snippet.html")
webView
}
and then present the webview in a bottomsheet fragment like so:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (webController == null) {
// activity restarted without original context
dismiss()
} else {
webController?.webView?.visibility = View.VISIBLE
webController?.let {
fragment_web_view?.addView(webController?.webView)
}
}
}
I observe these undesirable behaviors:
The webview's network requests all get stuck at pending when being backgrounded for around 2 min
If I persist the webview using a singleton, the webview stops making network request after the webview is presented and then dismissed
If I never present the fragment, the webview works fine no matter how long I wait
Requests start normal but stays pending after a while
But in these two scenarios the webview works fine.
If I keep the webview on screen all requests work fine.
If I keep presenting and dismissing the webview, all requests works fine.
Is there something that I don’t understand about the android webview that may have caused this issue? In order to refresh the webview, I need to reinitialize it to make the requests work again.
Looks like this is an issue with lates version of WebView. Can you open play market on the device find Android System WebView and try to downgrade it. Form me everything works fine on version 74 and stuck in pending on version 99. Let me know if it works same for you or you already found a reason?

Minimized video call and shared view with Zoom SDK

I'm trying to integrate Zoom SDK meetings in an Android app. I've struggled for a while now with using the custom meeting ui and learning how to use Zoom's video view called MobileRTCVideoView. Here's the interface I would like to create:
What I've tried:
Studied Zoom's sample apps on Github.
Studied Zoom's documentation for customized meeting ui.
Asked on the developer forum.
Read related threads on the developer forum.
However, I still don't understand how to implement it, and would very much appreciate some explanation as to how to use MobileRTCVideoView, and achieving the meeting ui illustrated on the image. The meetings should only hold up to two users at a time.
I initialize the Zoom SDK with API Key and Secret, and use email login. I enable the custom meeting ui with:
zoomSDK!!.meetingSettingsHelper.isCustomizedMeetingUIEnabled=true
I start an instant meeting with:
val meetingService=zoomSDK!!.meetingService
val opts=InstantMeetingOptions()
opts.no_driving_mode = true
opts.no_invite = false
opts.no_meeting_end_message = false
opts.no_titlebar = false
opts.no_bottom_toolbar = false
opts.no_dial_in_via_phone = true
opts.no_dial_out_to_phone = true
opts.no_disconnect_audio = true
meetingService.startInstantMeeting(this,opts)
I've tried to follow the sample apps by creating another activity for the custom meetings, but apparently the class and the code is not complete:
class CustomMeetingActivity: FragmentActivity() {
private var zoomSDK:ZoomSDK?=null
private var inflater:LayoutInflater?=null
private var normal_view:View?=null
private var video_view:MobileRTCVideoView?=null
private var video_manager:MobileRTCVideoViewManager?=null
private var meeting_service:MeetingService?=null
private var in_meeting_service:InMeetingService?=null
private var share_view:MobileRTCShareView?=null
private var meeting_video_view:FrameLayout?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
zoomSDK=ZoomSDK.getInstance()
meeting_service = ZoomSDK.getInstance().meetingService
in_meeting_service=ZoomSDK.getInstance().inMeetingService
if(meeting_service==null || in_meeting_service==null){finish();return}
setContentView(R.layout.custom_meeting_layout)
inflater=layoutInflater;
normal_view = inflater!!.inflate(R.layout.meeting_content_normal,null)
meeting_video_view = findViewById<View>(R.id.meetingVideoView) as FrameLayout
share_view = findViewById<View>(R.id.sharingView) as MobileRTCShareView
video_view=normal_view!!.findViewById(R.id.videoView) as MobileRTCVideoView
}
}
Added the activity in the manifest:
<activity
android:name="com.mypackage.appname.CustomMeetingActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:theme="#style/ZMTheme.SubWindow">
</activity>
Solid advice I can give is:
Override or reuse their existing Sample to get started. (Though their sample app looks like it was done in a rush)
Don't user their styles, override their styles and use them.
Scan/Study the MyMeetingActivity. Most of the heavy lifting is done in it already.
Check both of their samples. If you cannot figure out sharedView from MyMeetingActivity, then it looks like you haven't studied hard enough
I have worked a lot on this over the last few weeks. Customized UI is working well. I am looking to make the Gallery view. We have loads of features and functionality that we added and reused. Over all it was a bumpy ride, but still went smooth as I spent time on it.
I don't understand why this question is not yet answered. Unfortunately I am too busy to actually write code out for you, especially since I am not even developing in Kotlin. Sorry. Hope you figure it. If I implement the gallery view, then maybe I can come back and give you some pointers. Good Luck

Categories

Resources