I have a PWA (a Webview) made with both WebViewClient and WebChromeClient in Kotlin.
The main code of the PWA is this one, where I set all the options for both webview clients:
binding.webView.settings.javaScriptEnabled=true
binding.webView.settings.javaScriptCanOpenWindowsAutomatically=true
binding.webView.settings.domStorageEnabled=true
binding.webView.settings.allowFileAccess=true
binding.webView.webChromeClient = object : WebChromeClient() {
override fun onPermissionRequest(request: PermissionRequest) {
request.grant(request.resources)
}
}
binding.webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
view.loadUrl(url)
return false // then it is not handled by default action
}
}
The web page that opens this webview has an option to take pictures with camera.
Have been working for 5 years, and it used to work in an old PWA made with Java, but now in the new one with Kotlin I can't make work the camera.
I had problems with camera permissions but not anymore (I fix that), it ask for camera permissions correctly:
But when I tried to open the camera this is what I get:
But if I open directly on Chrome (on the mobile) it works ok:
so the problem is not on the webpage but in the PWA.
What could be? any hint please
Related
I'm trying to serve real react app on electron app. It doesn't mean I'm developing electron app with react. I've created a react app and injected it into electron app. (Like slack, it will serve as a web application and desktop application.) But I'm confused that send desktop notifications.
Now the main question is:
How can I get the application type. I mean, is user using my app on web or on desktop. How can I get this?
Thank you :)
There are many ways to detect whether you are running in a desktop environment or not.
You can check the User-Agent and you can set the userAgent value in Electron when you call loadURL.
Another way is declaring a global variable using a preload script.
// main process
new BrowserWindow({
webPreferences: {
preload: "preload.js",
},
});
// preload.js
// you don't need to use contextBridge if contextIsolation is false
// but it's true by default in Electron 12
const { contextBridge } = require("electron");
contextBridge.exposeInMainWorld("IN_DESKTOP_ENV", true);
// renderer process (your React world)
if (globalThis.IN_DESKTOP_ENV) {
// do something...
}
I found this native android code for what I am trying to achieve
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(newVideoPath), "video/mp4");
startActivity(intent);
(Android intent for playing video?)
But I can't figure out how to use apply it in react native with the Linking.sendIntent api, or if that api is even capable of doing it.
I also tried this module, but it failed to build the project with the error method does not override or implement a method from a supertype
I don't want to write a native module for this.
Turns out you can't send data with an intent with the built in sendIntent api, however there's a handy library that's capable of doing that (react-native-send-intent).
So now I am able to achieve what I wanted like so:
import { Linking, Platform } from "react-native";
import SendIntentAndroid from "react-native-send-intent";
export function playVideo(url){
var fn = Platform.select({
android(){
SendIntentAndroid.openAppWithData(
/* "org.videolan.vlc" */null,
"https://www.w3schools.com/html/mov_bbb.mp4",
"video/*"
).then(wasOpened => {});
},
default(){
Linking.openURL(url).catch(err => {});
}
});
fn();
}
Despite the library not offering a function for launching the default app for a url, you can achieve it by passing in null as the packagename, since the function it uses under the hood Intent.setPackage(String packageName), accepts null as a value.
I have an electron app that will just wrap a remote page while adding some extra features. With the following code the page loads and works. When the remote page fires some notifications using the notification API those notifications show up when the electron app is minimized. My problem is that when clicking on those notifications the app does not get put to front like it does when opening the remote page on any other browser directly. I could test this only for Ubuntu 19.10 Linux (Gnome 3).
Any idea if I need to configure something for that or if this is a bug with Electron/Ubuntu/Gnome?
const {app, shell, BrowserWindow} = require('electron');
let mainWindow;
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 1024,
height: 786,
});
mainWindow.setMenu(null);
mainWindow.setTitle('My app – Connecting…');
mainWindow.loadURL('https://some.url.somwhere');
// Emitted when the window is closed.
mainWindow.on('closed', () => {
mainWindow = null
})
}
app.on('ready', createWindow);
First of it is NOT a good idea to wrap a remote page unless you really know what you are doing as if you were redirected to a malicious page the page would have access to run code in the operating system. I would suggest giving this a read to make sure you're being safe.
Secondly the notification HTML5 API (runs in renderer) and notification module (runs in main) both do not have default behaviour to bring the page to the front when the notification is clicked you must add this behaviour yourself.
Because your loading a remote page you're probably using the notification module therefore it would be accomplished like follows:
notification = new Notification({title: "Message from: "+result[i].messageFrom,body: messagebody,icon: path.join(__dirname, 'assets','images','icon.png')})
notification.show()
notification.on('click', (event, arg)=>{
mainWindow.moveTop()
mainWindow.focus()
})
I'm trying to build a simple webView application for MacOS, but it doesn't seem to work. I've linked the code to the storyboard, imported WebKit, but nothing seems to work. After I finish the build, and try to test it, the window keeps gray. There are no errors involved. Does anyone know what I did wrong?
CODE:
import Cocoa
import WebKit
class ViewController: NSViewController {
#IBOutlet var webView: WebView!
override func viewDidLoad() {
super.viewDidLoad()
webView.mainFrame.load(URLRequest(url: URL(string: "http://apple.com")!))
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
You should be using a WKWebView instead of a WebView. WKWebView replaced WebView in macOS 10.10.
#IBOutlet var webView: WKWebView?
To load a webpage create a URL request with the webpage's URL. Call the web view's load() function to load the webpage with the URL request. The following code should load Apple's website in a WKWebView:
override func viewDidLoad() {
super.viewDidLoad()
loadWebContent()
}
func loadWebContent() {
if let myURL = URL(string: "https://www.apple.com") {
let myRequest = URLRequest(url: myURL)
webView?.load(myRequest)
}
}
One last thing you have to deal with is the app sandbox. Xcode projects initially have the app sandbox turned on. The app sandbox is set initially to disallow any incoming and outgoing network connections. Either allow incoming and outgoing network connections or turn off the sandbox.
I've got web application with browser authentication before webpage is loaded so in automated test i am log in via http://user:password#domain but when i am entering wrong credentials, pop up would not disappear it would wait for correct credentials. But i want to test if there is a access to webpage with wrong credentials, every browser is closing without problem, but IE is throwing
modal dialog present
i was trying to use
driver.SwitchTo().Alert().Dismiss();
but it doesn't work.
any idea how to close that pop up authentication?
Authentication popup is NOT generated by Javascript / it is not a javascript alert. So It can not be handled by WebDriver.
You did not mention the programming language you use. Your sample code seems to be in C#. In Java - we have a java.awt.Robot to simulate keyboard events. You might have to find C# equivalent to press the ESC key.
Robot robot = new Robot();
//Press ESC key
robot.keyPress(InputEvent.VK_ESCAPE);
robot.keyRelease(InputEvent.VK_ESCAPE);
In project I currently work in I decided to take completely another approach. I had similar situation of NTLM authentication but I'm pretty sure that for basic authentication it will work as well. I wrote simple chrome extension which utilizes listener on chrome.webRequest.onAuthRequired. Additionally, by putting additional methods in content script to communicate with background script I've managed a way to change credentials on the fly without caring about annoying windows.
background.js:
var CurrentCredentials = {
user: undefined,
password: undefined
}
chrome.runtime.onMessage.addListener(function(request) {
if(request.type === 'SET_CREDENTIALS') {
CurrentCredentials.user = request.user;
CurrentCredentials.password = request.password;
}
});
chrome.webRequest.onAuthRequired.addListener(function(details, callback) {
if(CurrentCredentials.user !== undefined && CurrentCredentials.password !== undefined) {
return {authCredentials:
{
username: CurrentCredentials.user,
password: CurrentCredentials.password
}
};
}
}, {urls: ["http://my-server/*"]}, ["blocking"]);
and content-script.js:
var port = chrome.runtime.connect();
window.addEventListener("message", function(event) {
if (event.source !== window)
return;
if (event.data.type && (event.data.type === 'SET_CREDENTIALS')) {
chrome.runtime.sendMessage({
type: 'SET_CREDENTIALS',
user: event.data.user,
password: event.data.password
});
}
}, false);
Extension must be packed as crx and added to ChromeOptions prior to driver initialization. Additionally, it is required to set credentials BEFORE actual call to site that needs authentication, so I browse simple html file on the disk and post a chrome message while being on the page: window.postMessage({type: 'SET_CREDENTIALS', user: arguments[0], password: arguments[1]}, '*') by using IJavascriptExecutor.ExecuteScript method. After it is done, no authentication window shows up and user is authentication as expected.