facebook / screenshot-tests-for-android

Generate fast deterministic screenshots during Android instrumentation tests
http://facebook.github.io/screenshot-tests-for-android
Apache License 2.0
1.74k stars 229 forks source link

WindowAttachment.setAttachInfo() fails for API 28 #274

Open sandeep-desai-ck opened 3 years ago

sandeep-desai-ck commented 3 years ago

same issue as the previous ticket, but still failing on API 28. The constructor for ViewRootImpl is the same in both APIs so I'm not sure why it's still failing in API 28 with NoSuchMethodException

kirillakhmetov commented 3 years ago

This is because it tries to use reflection on greylist API. So I suppose, if your app targets versions <28 it should work fine. Otherwise fix in the library needed.

if (Build.VERSION.SDK_INT >= 26) { viewRootImpl = cViewRootImpl .getConstructor(Context.class, Display.class) .newInstance(context, display);

https://developer.android.com/distribute/best-practices/develop/restrictions-non-sdk-interfaces

sandeep-desai-ck commented 3 years ago

Verified that the above suggestion (dropping target to below 28) does indeed work as an interim solution.

michaeltroger commented 3 years ago

If you don't have the option to downgrade the API there is another workaround that worked for me: You would explicitly allow calls to hidden APIs

build.gradle: androidTestImplementation 'org.lsposed.hiddenapibypass:hiddenapibypass:2.0'

Test:

@Test
fun screenshotButton() {
   val button = Button(getContext())
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
       HiddenApiBypass.addHiddenApiExemptions("L")
   }
   WindowAttachment.setAttachInfo(button)
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
       HiddenApiBypass.clearHiddenApiExemptions()
   }

   ViewHelpers.setupView(button).layout()
   Screenshot.snap(button).setName("button").record()
}

Since it only allow the hidden API for WindowAttachment.setAttachInfo I guess it's pretty safe and shouldn't influence the rest of the test behavior. There is also an option to allow hidden API without a library by using ADB. For my use case the library was a better fit though.

Might be helpful as well: https://stackoverflow.com/a/55970138/5155371

sergio-sastre commented 2 years ago

@michaeltroger Why not to create a PR to fix the issue?