I have a scenario where i need to enter email and click on submit button but when webdriver enters email and clicks on submit button an error is thrown "Email is Required" although webdriver entered the email which i can see. I have this issue on Firefox and Safari both on Desktop and mobile devices. With a bit of research i able to fix for Firefox with below javascript code.
JavascriptExecutor js = ((JavascriptExecutor)driver);
js.executeScript("var e=document.getElementById('email'); e.dispatchEvent(new Event('change')); e.dispatchEvent(new Event('blur')); return true;" );
But the same code does not work on mobile safari on real device. Could someone help in fixing this issue ?
Environment
Appium version - 1.6.5 Mac os : 10.12.6 Node.js version - 3.10.10
Mobile platform/version under test: - 10.3 Iphone 6 Real device Using
Appium desktop client Logs: <script
src="https://gist.github.com/mahesh-thuma/f02f6fdc81d48d4c0a16e2dd71412e0c.js"></script>
Figured out the issue. There is a small change in the email attribute from desktop ("email") to mobile ("Email"). Modified the javascript accordingly and i am able to proceed ahead. Though this is still an workaround but does the job. Closing this issue and Thanks to anyone investing time on this.
import Page from './page';
class YahooPage extends Page {
/**
* define elements
*/
get searchInput() { return browser.element('#yschsp'); }
get searchButton() { return browser.element('//div[#class="mag-glass"]'); }
get resultsList() { return browser.element('#results'); }
/**
* define or overwrite page methods
*/
open () {
super.open('https://search.yahoo.com') //provide your additional URL if any. this will append to the baseUrl to form complete URL
browser.pause(1000);
}
enterText (item) {
this.searchInput.clearElement();
this.searchInput.setValue(item);
}
search () {
this.searchButton.click();
}
isSearched () {
this.resultsList.waitForVisible(1000);
return this.resultsList.isVisible();
}
}
export default new YahooPage();enter code here
Related
I'm having problems with a piece of code that has worked before for years, but seems to have stopped working now.
I'm opening a window with a login form and I'm listening via a WebSocket for events regarding that login. After the login was successful, I want to close the window (that my script has opened and kept the reference to) after a short moment. I'm using the following code:
const windowManager = {
window: null,
eventType: null,
}
function openWindow({ url, eventType }) {
windowManager.window = window.open(url)
windowManager.eventType = eventType
}
function closeWindow({ eventType }) {
if (windowManager.window && windowManager.eventType == eventType) {
setTimeout(() => {
windowManager.window && windowManager.window.close()
windowManager.window = null
}, 100)
}
}
I have confirmed that windowManager.window.close() is called and does not thrown an error. I have also extracted the code from the application and tested it separately and it still won't close the window. As I said, this piece of code has worked before and was not changed in the past two years or so.
I'm using the following browsers:
Safari 15.3
Firefox 97.0b9 (Developer Edition)
Chromium 94.0.4606.61
I'm grateful for any pointers which could help resolve this issue. Thanks a lot!
After figuring out that the above code worked totally fine with other sites like Google or GitHub, I found that the Cross-Origin-Opener-Policy header in our auth backend (which was the site that was opened with the code) is the culprit. We had just updated Helmet to version 5 which added the header by default.
Our solution was to set Cross-Origin-Opener-Policy to same-origin-allow-popups on both source and target window (which are hosted on the same origin, but served by different servers). It also worked when setting it to unsafe-none for the target window without setting it at all on the source window.
What I am doing
I am creating a web form that is being used as a QR code to open an application installed in an android / IOS phone. When the user scans the QR code the phone shall run the web form and the web form will check if the application is installed inside the phone, if the application is installed, the web form will open the application, if not it will open the google play store/app store web page based on which OS system is being used.
My problem
Right now my problem is that I do not know what is the name/id of the application to trigger/open it, the only thing I about the app know is that it is called Rymtime inside the setting and also the home screen. The application's google play store link is at here and here for the app store.
PS. I do not own/create the application and do not have any access to modify its code.
What I have tried
I have tried to put its name directly into the code:
window.location = "Rymtime://";
I have also tried to put the "id" thingy found inside its google play store website "www...id=com.time2clock.wai.timeemployee"
window.location = "com.time2clock.wai.timeemployee://";
My Code
I created my code based on this stack overflow question.
Below is my code:
<body>
...
<button name="data1" type="button" onclick="getOS()">Click</button> //I use button to test out the function
...
</body>
<script type="text/javascript">
function getOS() {
var userAgent = window.navigator.userAgent,
platform = window.navigator.platform,
windowsPlatforms = ['Win32', 'Win64', 'Windows', 'WinCE'], //as I do not own an Iphone I use this to test out the IOS part
iosPlatforms = ['iPhone', 'iPad', 'iPod'],
os = null;
if (iosPlatforms.indexOf(platform) !== -1) {
ios();
} else if (windowsPlatforms.indexOf(platform) !== -1) {
ios(); //as I do not own an Iphone I use this to test out the IOS part
} else if (/Android/.test(userAgent)) {
android();
}
}
function ios() {
setTimeout(function () { window.location = "https://apps.apple.com/my/app/rymtime/id1447217174"; }, 25);
window.location = "Rymtime://"; //I do not test this part because I do not own an Iphone an I am using window to see if the code is being executed, I only check if the website above is runned
}
function android() {
setTimeout(function () { window.location = "https://play.google.com/store/apps/details?id=com.time2clock.wai.timeemployee"; }, 25);
window.location = "Rymtime://"; //The application is not executed thus it redirect to the play store page.
}
</script>
Btw is the location of an application installed inside a phone the same as the others? Like this:
somefile\somefile\packageName
Or something like this:
Username(differ)\somefile\somefile\packageName
Thanks.
I am not sure what it is for IOS but I found out that I can just add &launch=true at the end of the URL of the application's google play store page to launch the app if it is installed.
I have the following method which works on the 1st call, however if I hit the Esc key and then try my FullScreen button nothing happens. Debugging the code shows the else is not executing so document.body.requestFullScreen() is being called again but it has no effect??
What did I miss?
/**
* Full Screen Mode
+ works on Windows7 Chrome v80 and Android Chrome.
- 20180415
- 20200417 Moved from ChannelsTitleComp
*/
FullScreenToggle() {
// document.body.requestFullscreen() works on Windows Chrome and Android Chrome.
// https://stackoverflow.com/questions/53048372/how-to-programmatically-switch-display-from-standalone-to-fullscreen-in-pwa
if (document.body.requestFullscreen) {
document.body.requestFullscreen()
}
else {
Log.Write(this, "requestFullscreen", document.body.requestFullscreen)
document.exitFullscreen()
}
did not incorporate something like this for a toggle YET
// https://developers.google.com/web/fundamentals/native-hardware/fullscreen/
if (document.fullscreenElement)
document.exitFullscreen()
Thank you for your insights.
20200418 16:42 Update
A reply from Oscar requested to print the value of requestFullscreen the second time thru. I did and t seems to be the same according to the following console output.
Here is the code I used
Trying to authenticate users on my ionic application through an external service and I need to use cordovas In app browser! The code works perfectly on android however on iOS the "loadstop" event never fires and thus, the browser never redirects itself back to the application. The code I have looks like this:
$rootScope.$on('$cordovaInAppBrowser:loadstop', function (e, event) {
console.log('inappbrowser loaded', event);
var regex = /* regex to determine if url is correct redirected url */
var res = regex.test(event.url);
alert('loaded: ' + event.url);
alert('regex result: ' + res);
if(res === true) {
$cordovaInAppBrowser.close();
}
});
if(okta) {
if (typeof window.localStorage.msRefreshToken === 'undefined') {
document.addEventListener('deviceready', function () {
$cordovaInAppBrowser.open('urlforExternalservicehere', '_blank', options);
}, false);
} else {
TokenStore.refreshAccessToken();
}
}
when the code is run no alert appears on the screen. Also, once the app has reached the external service and the username of the user is entered, it is then redirected to another url, which the user will then use another set of credentials to authenticate against. This in turn returns a token for the application to authenticate use.
Thus, in a perfect iOS world where it matches the current android experience, the loadstop event fires three times, and the third time the "loadstop" event would fire and the regex would return true and close the in app broswer.
If I need to supply more code to help solve this issue please let me know!
Cordova Version: 4.2.0
Ionic: 1.4.5
iOS: 8 and 9
Using NgCordova for Cordova functionality
UPDATE: when running the application on an emulator and checking the console logs, I find this error:
Error: Module cordova-plugin-inappbrowser.inappbrowser does not
exist., http://10.117.1.46:8100/cordova.js, Line: 1402
I have the plugin installed so I don't know how its missing the plugin. Does anyone have a remedy for this? Thanks!
iabRef = window.open('http://XYZ.php', '_blank', 'location=no,toolbar=no');
iabRef.addEventListener('loadstart', iabLoadStart);
iabRef.addEventListener('loadstop', iabLoadStop);
iabRef.removeEventListener('loaderror', iabLoadError);
iabRef.addEventListener('exit', iabClose);
iabRef.addEventListener('loadstart', function(event) {
if (event.url.match("mobile/close")) {
iabRef.close();
window.location = 'index.html';
}
}
);
Problem was my iOS platform wasn't latest.
So when you developing apps using cordova make sure your platform versions and plugins are up-to date with OS upgraded.
So all I had to do is
Removing iOS platform.
cordova platform rm ios
Adding iOS platform - Latest Version
cordova platform add ios
Removing the plugin cordova-plugin-inappbrowser
cordova plugin remove cordova-plugin-inappbrowser
Adding the plugin cordova-plugin-inappbrowser - Latest Version
cordova plugin add cordova-plugin-inappbrowser
I'm using the HTML5 notification API to notify the user in Chrome or Firefox. On desktop browsers, it works. However in Chrome 42 for Android, the permission is requested but the notification itself is not displayed.
The request code, works on all devices:
if ('Notification' in window) {
Notification.requestPermission();
}
The sending code, works on desktop browser but not on mobile:
if ('Notification' in window) {
new Notification('Notify you');
}
Try the following:
navigator.serviceWorker.register('sw.js');
Notification.requestPermission(function(result) {
if (result === 'granted') {
navigator.serviceWorker.ready.then(function(registration) {
registration.showNotification('Notification with ServiceWorker');
});
}
});
That is, use ServiceWorkerRegistration»showNotification() not new Notification().
That should work on Android both in Chrome and in Firefox — and on iOS in Safari, too.
(The sw.js file can just be a zero-byte file.)
One caveat is that you must run it from a secure origin (an https URL, not an http URL).
See https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/showNotification.
If you already have a service worker registered, use this:
navigator.serviceWorker.getRegistrations().then(function(registrations) {
registrations[0].showNotification(title, options);
});
Running this code:
if ('Notification' in window) {
Notification.requestPermission();
}
Console in Chrome DevTools shows this error:
Uncaught TypeError: Failed to construct ‘Notification’: Illegal
constructor. Use ServiceWorkerRegistration.showNotification() instead
A better approach might be:
function isNewNotificationSupported() {
if (!window.Notification || !Notification.requestPermission)
return false;
if (Notification.permission == 'granted')
throw new Error('You must only call this \*before\* calling
Notification.requestPermission(), otherwise this feature detect would bug the
user with an actual notification!');
try {
new Notification('');
} catch (e) {
if (e.name == 'TypeError')
return false;
}
return true;
}
Function Source: HTML5Rocks
I had no trouble with the Notification API on Windows Desktop. It even worked without issues on Mobile FF. I found documentation that seemed to indicate Chrome for Android was supported too, but it didn't work for me. I really wanted to prove the API could work for me on my current (2019) version of Chrome (70) for Android. After much investigation, I can easily see why many people have had mixed results. The answer above simply didn't work for me when I pasted it into a barebones page, but I discovered why. According to the Chrome debugger, the Notification API is only allowed in response to a user gesture. That means that you can't simply invoke the notification when the document loads. Rather, you have to invoke the code in response to user interactivity like a click.
So, here is a barebones and complete solution proving that you can get notifications to work on current (2019) Chrome for Android (Note: I used jQuery simply for brevity):
<html>
<head>
<script type="text/javascript" src="libs/jquery/jquery-1.12.4.min.js"></script>
<script>
$( function()
{
navigator.serviceWorker.register('sw.js');
$( "#mynotify" ).click( function()
{
Notification.requestPermission().then( function( permission )
{
if ( permission != "granted" )
{
alert( "Notification failed!" );
return;
}
navigator.serviceWorker.ready.then( function( registration )
{
registration.showNotification( "Hello world", { body:"Here is the body!" } );
} );
} );
} );
} );
</script>
</head>
<body>
<input id="mynotify" type="button" value="Trigger Notification" />
</body>
</html>
In summary, the important things to know about notifications on current (2019) Chrome for Android:
Must be using HTTPS
Must use Notification API in response to user interactivity
Must use Notification API to request permission for notifications
Must use ServiceWorker API to trigger the actual notification
new Notification('your arguments'); This way of creating notification is only supported on desktop browsers, not on mobile browsers. According to the link below. (scroll down to the compatibility part)
https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API/Using_the_Notifications_API
For mobile browsers below is the way you create a notification (this also works on desktop browsers)
navigator.serviceWorker.ready.then( reg => { reg.showNotification("your arguments goes here")});
Tested on browsers using webkit engine.
For more information please visit below links:
https://developers.google.com/web/updates/2015/05/notifying-you-of-changes-to-notifications
https://developers.google.com/web/fundamentals/push-notifications/display-a-notification