Flutter Web - how to test flutter web application opens in Chrome on desktop? - flutter

There is a button on a web page that makes an API call to third party application. And in return third-party application gets rendered on a web page.
Now, the third-party application (https://goknow.me/#/) is developed in flutter and I know nothing about flutter. I'm using java, selenium and webdriver for end to end testing. I'm using same set of tools for the rest of the application and it's working fine.
While inspecting in chrome, the DOM look like this:
Flutter application has a form and I want to find an element so that I can send inputs during testing automation. By searching online I found this appium-flutter-driver. I've also included the required jar in my project. With selenium webdriver I'm not able to find an element in flutter application that renders in Chrome browser on desktop.
Here's the code:
import pro.truongsinh.appium_flutter.FlutterFinder;
import pro.truongsinh.appium_flutter.finder.FlutterElement;
protected FlutterFinder find;
WebElement iframe = driver.findElement(By.xpath("//iframe[#id='know-iframe']"));
driver.switchTo().frame(iframe);
find = new FlutterFinder(driver);
FlutterElement elm = find.text("Email");
elm.click();
elm.sendKeys("hello world");
During testing automation I want to select fields in form and send inputs to those fields.
How to find an element in flutter web application that renders in another web application in Chrome browser on desktop?

Flutter Web is very different from normal web frameworks such as React or Vue. Looking at the official doc, it renders either into HTML elements (but still not the usual elements you see everyday), or directly draw onto a Canvas.
In addition, since it is a third-party app, it is mostly likely that you are not able to change their code. Thus, your appium-flutter-driver mostly will not work, because it says:
Under the hood, Appium Flutter Driver use the Dart VM Service Protocol with extension ext.flutter.driver, similar to Flutter Driver, to control the Flutter app-under-test (AUT).
You know, Dart VM service is only available when you run the Flutter app by source code in debug mode, or at least when you have control to the source code.
Therefore, my suggestion is: Can you treat the Flutter application as a "picture" instead of a DOM tree, and try to locate the buttons?

you can try using io.github.sukgu that helps you to work on the shadow elements. I was able to automate the scenario that you mentioned. Below is the detailed code.
Step 1 add the below dependency
<!-- https://mvnrepository.com/artifact/io.github.sukgu/automation -->
<dependency>
<groupId>io.github.sukgu</groupId>
<artifactId>automation</artifactId>
<version>0.1.3</version>
</dependency>
Step 2 use the below import in the test file
import io.github.sukgu.*;
Step 3 Below is the entire code that worked for me
WebDriver driver = new ChromeDriver();
driver.get("https://goknow.me/#/");
WebDriverWait wait = new WebDriverWait(driver,20);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("know-iframe")));
Shadow shadow = new Shadow(driver);
WebElement emailField = shadow.findElement("input[id='email']");
emailField.sendKeys("hello world");

Flutter team recommends using Flutter for "app-centric experiences" as "Progressive Web Apps, Single Page Apps, Existing Flutter mobile apps", but Flutter web app can also be embedded in a iframe tag.
They say:
At this time, Flutter is not suitable for static websites with text-rich flow-based content. For example, blog articles benefit from the document-centric model that the web is built around, rather than the app-centric services that a UI framework like Flutter can deliver.
You can read more about how a Flutter web app is deployed here.
When a Flutter app is built for the web, the page is rendered in 2 ways:
HTML renderer (on mobile browsers)
CanvasKit renderer (on desktop browsers)
I hope now you know a little more about Flutter framework. 🙂

Related

Flutter Web Get Chrome Extension info from Polkadot.js web3Enable

I am hoping to confer on a strategy for a flutter web app (as can ignore mobile cases here) to get chrome extension info for a Polkadot.js wallet from the Polkadot browser extension.
My first thought is to use dart's JS library and use the Polkadot extension JS package and then try and pull the info from there. However, I'm not sure how to properly use this in flutter as it is a whole package full of dependencies, not just a single JS file. Also it is in TS not JS. Any thoughts here?
Eg., I need a JS file to be able to call this; and for flutter to in turn call the JS file:
import {
web3Enable,
} from '#polkadot/extension-dapp';
By writing out a "bridging" layer, you can do it easily.
Firstly, create a normal javascript (or typescript) application (nothing related to Flutter). You should be able to happily use the polkadot lib in your js/ts code without any problem. You may need to learn a bit about how to develop js code normally (e.g. you can depend on polkadot using npm, etc).
One small thing is that, you should "expose" some object publicly in your js/ts code. For example, your code may look like window.myFancyFunction = function() { call_some_polkadot_function(); }. Of course you can do more things like exposing other functions/objects/...
Then, you can bundle this normal js/ts application into a .js file. This is still very normal for js/ts developers and should have nothing special to deal with here, and you still do not need to touch Flutter at this stage.
Next, load this single-filed .js file when you are loading your Flutter Web application. You may simply do this by editing your Flutter Web's html file and add <script src="my_single_filed_js_mentioned_above.js" />. Notice that, when loading this script, it simply sets window.myFancyFunction and does not do anything more. Still very trivial here, should have no problem.
Lastly, in your Flutter Web code, i.e. Dart code, call that window.myFancyFunction function. For example, Flutter Web : How to run javascript using dart js says you can do import 'dart:js' as js; js.context.callMethod('myFancyFunction', ['some arguments']);

Unable to perform the action on android webview

I am using Robot Framework with python. I have a page that has a web view. I am able to find the element through Appium inspector and also through the Chrome Dev tools. But those locators are not working. The test case passes but it does not click on that element.
Is there any work around for this issue?
Did you try the class name locator?
driver.find_element_by_class_name()

Testing Flutter apps with Cypress

Is it possible to test Flutter applications using the Cypress framework instead of using the built-in testing components that Flutter provides? If so, what are the pros & cons of both for Flutter testing if I know Cypress well?
Yes, technically, it's possible.
Here's a spec that passes with the basic flutter counter app:
describe('Counter app', () => {
beforeEach(() => {
cy.visit('http://localhost:_example_port_/#/')
cy.get('flt-semantics-placeholder').click({force: true})
})
it('Increments on button press', ()=>{
cy.get(`[aria-label="0"]`)
cy.get(`[aria-label="Increment"]`).click()
cy.get(`[aria-label="1"]`)
})
})
To explain, if you enable semantics by clicking on the hidden 'flt-semantic-placeholder' element, flutter adds a semantics layer used by screen readers. Widgets with tooltips and text are automatically assigned aria-labels, which Cypress can use to find and click on elements. (You can get more control over these labels using a Semantics Widget.)
I found this worked for the canvas renderer, but it crashed when I tried to run multiple test cases in the same run. So, use the html renderer, ie run flutter for the test with something like:
flutter run -d chrome --web-renderer html --web-port 3443
Okay, so clicking a button is pretty straightforward. What about other interactions?
Inputing text into a field:
Pretty straightforward. See this example.
Simulating a scroll event:
In short, no solution yet. See this markdown.
Simulating drag and drop:
Not likely. See this markdown.
Now for the pros and cons...
Pros:
Cypress is more user friendly than the integration testing flutter provides. Being able to easily hot reload tests, and being able to click around and inspect a live state of a failing test are nice features.
Cons:
Can't (yet) simulate scroll or drag.
Flutter web isn't too performant, and in particular the first load takes a long time. Tests are slow running.
Nothing indicates either the Flutter team or the Cypress team have any plans to support testing Flutter with Cypress.
As of this posting, no online guides or articles for testing Flutter with Cypress.
See also:
What are the tags, <flt-*> generated by Flutter for Web?
https://www.didierboelens.com/2018/07/semantics/

Integrate an App Widget into an ionic project

I'm developing an app widget on Android Studio beside an ionic project.
My goal is to to integrate my app widget into the ionic project permitting users having access to the widget by downloading the app.
I started copying pasting some file into the folder platform/android/src
but I get the error package R does not exist.
I don't know if it is the right way to do it.
If so, which library shall I import to fix this error. I already tried the android.jar from the android-sdk.
Is there any other easiest way to achieve this?
I just want to precise that the widget doesn't communicate with the ionic app, it make just http request to a Rest API.
It is because the hybrid does not have the Class R that manages that part. I'll leave some examples of how I do.
Instead of using R.layout.new_app_widget
context.getPackageName(),context.getResources().getIdentifier("new_app_widget", "layout",context.getPackageName());
or
context.getResources().getIdentifier("new_app_widget", "layout",context.getPackageName());
Instead of using R.id.btn_action
context.getResources().getIdentifier("btn_action", "id",context.getPackageName());
Instead of using R.string.app_name
context.getResources().getIdentifier("app_name", "string",context.getPackageName());
Instead of using R.drawable.icon
context.getResources().getIdentifier("icon", "drawable",context.getPackageName());

Does selenium support IE with google frame add on installed on it?

Selenium is able to load Chrome Frame pages. The problem is that once you load the page in IE with Chrome Frame plugin, the tag appears as empty. Selenium tries to identify elements using the DOM structure, but the way IE and Chrome Frame plugin works, rendering
and DOM tree are taken over by the Chromium code and IE gets an empty DOM.
So i guess, selenium doesn't support IE with google frame add-on installed on it?
Has anyone worked around this problem?
Thanks
This question has been asked and answered on the Selenium user's mailing list. The IE driver doesn't work with the Google Chrome Frame add-on, and there are no plans to implement support for it to work with the Chrome Frame add-on. Either you want to test the operation of your website under Chrome (in which case you should use the ChromeDriver), or you want to test it under IE (in which case you should use the IE driver). If you can point to a specific case where using the website with the Chrome Frame add-on behaves differently than the way it behaves with the Chrome standalone browser, you might be able to make a case to revisit the issue. Furthermore, remember that Selenium is an Open Source project, and you are welcome to make changes and submit patches to the code at any time.
Watir WebDriver has the same issue.
Selenium core, the part that loads in the target browser and executes tests does work and can be run independently. So, if you have a Selenium test suite in HTML form, it can be run in GCF using the following steps:
Configure a web server to opt all URLs into chrome frame using HTTP header as described here: http://www.chromium.org/developers/how-tos/chrome-frame-getting-started#TOC-Making-Your-Pages-Work-With-Google-
Host your test suite under '/tests' folder on this web server. Lets say the suite is my_test_suite.html.
Host the selenium core folder as the '/core' on the server
Now restart the server.
Run the suite with this URL: http:///core/TestRunner.html?test=tests/my_test_suite.html&auto=true