Is it possible to click button with PuppeteerSharp in headless mode? - c#

I'm developing bot. He is working normally when headless mode is set to false. Whenever I start it with headless mode set to true, it throws timeout errors because it didn't find my selectors.
I thought it would be maybe because of different resolution in both modes. So I set static default viewport. It fixed nothing.
Is it even possible to click with pupeeteer in headless mode? I would like to achieve that so I don't have multiple chromes open.
Creating browser
_browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true,
ExecutablePath = #"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe",
Args = new[] { "--disable-web-security", "--disable-infobars" },
DefaultViewport = new ViewPortOptions { Height = 1080, Width = 1920},
}) ;
var pagesAsync = await _browser.PagesAsync();
_page = pagesAsync.FirstOrDefault();
const string logInButtom = "#__layout > div > nav > div.uinfo-wrapper.flex > div.login-btn-wrap > button";
await _page.WaitForSelectorAsync(logInButtom);
await _page.ClickAsync(logInButtom);
System.Threading.Thread.Sleep(1500);
Debug.WriteLine("Succesfull login show");
Here is piece of code that works headless = false. Doesnt work headless = true
await _page.WaitForSelectorAsync(logInButtom); throws time out.

Related

How to set geolocation in headless chrome mode?

I need to run UI autotests in headless mode in chrome browser. But the standard settings
options.AddUserProfilePreference("profile.default_content_setting_values.geolocation", 1);
options.AddUserProfilePreference("profile.managed_default_content_settings.geolocation", 1);
in headless mode do not work.
I read that we can set it to manual geolocation by emulating actions in devtools.
My code C#:
var devTools = Driver as IDevTools;
var session = devTools!.GetDevToolsSession();
var typeList = new[] { PermissionType.Geolocation };
var commandPermission = new GrantPermissionsCommandSettings();
commandPermission.Permissions = typeList;
commandPermission.Origin = "https://www.gps-coordinates.net/my-location";
session.SendCommand(commandPermission);
var command = new SetGeolocationOverrideCommandSettings();
command.Latitude = 35.689487;
command.Longitude = 139.691706;
command.Accuracy = 100;
session.SendCommand(command);
But unfortunately it doesn't work.
Could you suggest what could be the problem?
**
UPDATED
**
As a result, the code above worked, but I still could not click on the button, due to the lock screen with a message about permission to determine geolocation.
As a result, with the help of a JS script, I was able to set the geolocation
IJavaScriptExecutor js = (IJavaScriptExecutor)Driver;
js.ExecuteScript("navigator.geolocation.getCurrentPosition = (cb) => {cb({ coords: { latitude: 35, longitude: 139 } })}");
That should be possible using the Chrome-devtoools-protocoll method Emulation.setGeolocationOverride (see https://chromedevtools.github.io/devtools-protocol/tot/Emulation/#method-setGeolocationOverride)
That's actually what you're doing. Maybe 1000 is too big for accuracy, try using 1

Frame # not found when using Puppeteer

I'm having issues with Puppeteer, I am trying to type in a textbox that is in an IFrame.
I have created a simple repo with a code snippet, this one contains an IFrame with a tweet from Twitter.
await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultChromiumRevision);
var launchOptions = new LaunchOptions
{
Headless = false,
DefaultViewport = null
};
launchOptions.Args = new[] { "--disable-web-security", "--disable-features=IsolateOrigins,site-per-process" };
ChromeDriver = await Puppeteer.LaunchAsync(launchOptions);
page = await ChromeDriver.NewPageAsync();
await page.GoToAsync(Url, new NavigationOptions { WaitUntil = new WaitUntilNavigation[] { WaitUntilNavigation.Networkidle0 } });
var selectorIFrame = "#twitter_iframe";
var frameElement1 = await page.WaitForSelectorAsync(selectorIFrame);
var frame1 = await frameElement1.ContentFrameAsync();
var frameContent1 = await frame1.GetContentAsync();
var frame1 = await frameElement1.ContentFrameAsync(); fails with Frame # not found, see image with error below.
Versions:
PuppeteerSharp 7.0
.Net Framework 6
Git example
Try to disable some of the security features that can be disabled when launching puppeteer.
Check in puppeteer chrome://flags/ in case there's something blocking iframe access, maybe is insecure content or maybe you have to be explicit about isolation trial.
My 2 cents on this, it should allow it to access it from non secure
Args = new[]
{
"--disable-web-security",
"--disable-features=IsolateOrigins,site-per-process,BlockInsecurePrivateNetworkRequests",
"--disable-site-isolation-trials"
}

C# Selenium/ChromeDriver Add User Profile Preference

I need to allow all cookies when running tests with selenium + chrome driver.
I am trying to add this as a profile preference using ChromeOptions.AddUserProfilePreference
I'm not 100% sure what the preference name should be to allow all cookies. I have referenced this doc https://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/pref_names.cc?view=markup
and have tried the following in my setup but its not having the desired effect.
options.AddUserProfilePreference("profile.block_third_party_cookies", false);
options.AddUserProfilePreference("security.cookie_behavior", 0);```
Here is my setup code
new DriverManager().SetUpDriver(new ChromeConfig());
var options = new OpenQA.Selenium.Chrome.ChromeOptions { };
options.AddArgument("–no-sandbox");
options.AddArguments("-disable-gpu");
options.AddArguments("-disable-dev-shm-usage");
options.AddArgument("-incognito");
options.AddArgument("-start-maximized");
options.AddUserProfilePreference("security.cookie_behavior", 0);
CurrentWebDriver = new ChromeDriver(options);
I ran into the same issue. I found that using the following helped me:
options.AddUserProfilePreference("profile.cookie_controls_mode", 0);
The advice that helped me find this, was to check the Chrome preferences file (in my case C:\Users\<user>\AppData\Local\Google\Chrome\User Data\Default\Preferences). I saved a copy with cookies blocked, then changed the setting to allow all cookies and compared the two versions, and that highlighted the affected control for me.
Looks like in Chrome v86 third-party cookies disabled by default: Chromium SameSite Updates.
I found a workaround to enable third-party cookies on the browser new tab start page (I'm using inputsimulator library to open a new tab because other methods do not open the appropriate page).
Here is C# code for IWebDriver extension:
using WindowsInput;
using WindowsInput.Native;
public static void EnableThirdPartyCookies(this IWebDriver driver)
{
var windowHandles = driver.WindowHandles;
// Activate Browser window
driver.SwitchTo().Window(driver.WindowHandles.Last());
// Open New Tab Ctrl + T
new InputSimulator().Keyboard.ModifiedKeyStroke(VirtualKeyCode.CONTROL, VirtualKeyCode.VK_T);
// Wait for open new tab
const int retries = 100;
for (var i = 0; i < retries; i++)
{
Thread.Sleep(100);
if (driver.WindowHandles.Count > windowHandles.Count)
break;
}
// Enable Third Party Cookies
if (driver.WindowHandles.Count > windowHandles.Count)
{
driver.Close();
driver.SwitchTo().Window(driver.WindowHandles.Last());
var selectedCookieControlsToggle = driver.FindElements(By.Id("cookie-controls-toggle"))
.FirstOrDefault(x => x.GetAttribute("checked") != null);
selectedCookieControlsToggle?.Click();
}
}
Using:
var chromeService = ChromeDriverService.CreateDefaultService();
var options = new ChromeOptions { };
options.AddArgument("–no-sandbox");
options.AddArgument("-incognito");
options.AddArgument("-start-maximized");
var driver = new ChromeDriver(chromeService, options);
driver.EnableThirdPartyCookies();
Here is Java code:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public void enableThirdPartyCookies(WebDriver driver) throws Exception {
ArrayList<String> windowHandles = new ArrayList<String> (driver.getWindowHandles());
// Activate Browser window
driver.switchTo().window(driver.getWindowHandle());
// Open New Tab Ctrl + T
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_T);
robot.keyRelease(KeyEvent.VK_T);
robot.keyRelease(KeyEvent.VK_CONTROL);
// Wait for open new tab
int retries = 100;
for (int i = 0; i < retries; i++)
{
Thread.sleep(100);
if (driver.getWindowHandles().size() > windowHandles.size())
break;
}
// Enable Third Party Cookies
if (driver.getWindowHandles().size() > windowHandles.size())
{
driver.close();
windowHandles = new ArrayList<String> (driver.getWindowHandles());
driver.switchTo().window(windowHandles.get(windowHandles.size() - 1));
List list = driver.findElements(By.id("cookie-controls-toggle"));
Optional<WebElement> selectedCookieControlsToggle = driver.findElements(By.id("cookie-controls-toggle")).stream()
.filter(x -> x.getAttribute("checked") != null).findFirst();
Optional.ofNullable(selectedCookieControlsToggle).get().get().click();
}
}
Using:
ChromeOptions options = new ChromeOptions();
options.addArguments("–no-sandbox");
options.addArguments("incognito");
options.addArguments("start-maximized");
WebDriver driver = new ChromeDriver(options);
enableThirdPartyCookies(driver);

Your connection is not secure - using Selenium.WebDriver v.3.6.0 + Firefox v.56

I'm writing tests with Selenium + C# and I face an important issue because I didn't found solution when I test my site with secure connection (HTTPS). All solutions I found on stackoverflow are out of date or doesn't work.
I tried to exercise all solutions from below question:
Selenium Why setting acceptuntrustedcertificates to true for firefox driver doesn't work?
But they did not help me solve the problem
Nor is it the solution of using Nightly FireFox.
Still, when the selenium loading Firfox browser, I see the page: "Your connection is not secure".
Configuration:
Firefox v56.0
Selenium.Firefox.WebDriver v0.19.0
Selenium.WebDriver v3.6.0
my code is:
FirefoxOptions options = new FirefoxOptions();
FirefoxProfile profile = new FirefoxProfile();
profile.AcceptUntrustedCertificates = true;
profile.AssumeUntrustedCertificateIssuer = false;
options.Profile = profile;
driver = new FirefoxDriver(FirefoxDriverService.CreateDefaultService() , options , TimeSpan.FromSeconds(5));
Drivers.Add(Browsers.Firefox.ToString() , driver);
Thank for your help!
Updates to my question here:
Note 1: To anyone who has marked my question as a duplicate of this question:
Firefox selenium webdriver gives “Insecure Connection”
I thought that it is same issue, but I need solution for C#, I try match your JAVA code to my above code
First, I changed to TRUE the below statment:
profile.AssumeUntrustedCertificateIssuer = true;
second, I create new FF profile ("AutomationTestsProfile")
and try to use it:
Try 1:
FirefoxProfile profile = new FirefoxProfileManager().GetProfile("AutomationTestsProfile");
try 2:
FirefoxProfile profile = new FirefoxProfile("AutomationTestsProfile");
I Run 2 options, but still the issue exists.
Note 2: I attached screenshot of my problem, it appears when the driver try to enter text to user-name on login page.
I noticed that when I open my site with FF, Firefox displays a lock icon with red strike-through red strikethrough icon in the address bar,
but near the username textbox not appears the msg:
"This connection is not secure. Logins entered here could be compromised. Learn More" (as you writed on the duplicate question),
So maybe there is a different problem?
You are setting the properties on the profile. The FirefoxOptions has a property AcceptInsecureCertificates, set that to true.
Forget the profile, this is what you want:
var op = new FirefoxOptions
{
AcceptInsecureCertificates = true
};
Instance = new FirefoxDriver(op);
For me, the profile setting AcceptUntrustedCertificates was not enough, I also had to set option security.cert_pinning.enforcement_level. My startup looks like
// no idea why FirefoxWebDriver needs this, but it will throw without
// https://stackoverflow.com/questions/56802715/firefoxwebdriver-no-data-is-available-for-encoding-437
CodePagesEncodingProvider.Instance.GetEncoding(437);
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
var service = FirefoxDriverService.CreateDefaultService(Environment.CurrentDirectory);
service.FirefoxBinaryPath = Config.GetConfigurationString("FirefoxBinaryPath"); // path in appsettings
var options = new FirefoxOptions();
options.SetPreference("security.cert_pinning.enforcement_level", 0);
options.SetPreference("security.enterprise_roots.enabled", true);
var profile = new FirefoxProfile()
{
AcceptUntrustedCertificates = true,
AssumeUntrustedCertificateIssuer = false,
};
options.Profile = profile;
var driver = new FirefoxDriver(service, options);
It works for me for following settings (same as above):
My env:
win 7
firefox 61.0.2 (64-bit)
Selenium C# webdriver : 3.14.0
geckodriver-v0.21.0-win32.zip
==============================
FirefoxOptions options = new FirefoxOptions();
options.BrowserExecutableLocation = #"C:\Program Files\Mozilla Firefox\firefox.exe";
options.AcceptInsecureCertificates = true;
new FirefoxDriver(RelativePath,options);

How to open multiple windows in a Windows 10 store app

I noticed that Microsoft Edge is capable of opening multiple windows, but i can not seem to find any example of this anywhere to open multiple windows.
I need to open multiple windows in my app for popups from my main windows WebView, i know this is possible but i dont know where to start nor is there anything on the internet
You can try following sample code
var currentAV = ApplicationView.GetForCurrentView();
var newAV = CoreApplication.CreateNewView();
await newAV.Dispatcher.RunAsync(
CoreDispatcherPriority.Normal,
async () =>
{
var newWindow = Window.Current;
var newAppView = ApplicationView.GetForCurrentView();
newAppView.Title = "New window";
var frame = new Frame();
frame.Navigate(typeof(MainPage), null);
newWindow.Content = frame;
newWindow.Activate();
await ApplicationViewSwitcher.TryShowAsStandaloneAsync(
newAppView.Id,
ViewSizePreference.UseMinimum,
currentAV.Id,
ViewSizePreference.UseMinimum);
});
Source: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/f1328991-b5e5-48e1-b4ff-536a0013ef9f/uwpis-it-possible-to-open-a-new-window-in-uwp-apps?forum=wpdevelop

Categories