Make Selenide undetectable using firefox (Kotlin) - selenium

while trying to use Selenide with Firefox driver in order to pull data out of HTML its being detected by websites.
I've tried many things across the internet but still no luck.
This is my code so far:
companion object {
#JvmStatic
#BeforeAll
fun setUpAll() {
val options = FirefoxOptions()
val profile = options.profile
profile.setPreference("dom.webdriver.enabled", false)
profile.setPreference("useAutomationExtension", false)
profile.setPreference("general.useragent.override", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:103.0) Gecko/20100101 Firefox/103.0")
options.addArguments("--disable-blink-features=AutomationControlled")
profile.setPreference("excludeSwitches", "enable-automation")
Configuration.browser = "firefox"
Configuration.browserSize = "1280x800"
Configuration.browserCapabilities = options
SelenideLogger.addListener("allure", AllureSelenide())
}
}
#BeforeEach
fun setUp() {
open("https://www.gmail.com/")
`$`(By.xpath("//input[#id='identifierId']")).setValue("someemail").pressEnter()
}
Please advice, thanks in advance

Related

How to use a UserAgent, headers and CookieContainer on WebView2?

Using a WebView2 control, I am trying to load into a webpage, but after I log into it, it seems it has some sort of block for generic browser that is not well configured because it keeps loading instead of proceed after the login, so I would like to add a CookieContainer and specify to use Cookies, add headers that specify that decompression is supported and what decompression methods are handled and User agent on WebView2 control same way this answer
works for HttpRequest.
Looking online I only found some code that I've tried to put together, but that's c# and I'm trying to convert it for vb.net but no online tool succeded to convert it yet
Private Sub webView2_NavigationStarting(sender As Object, e As Microsoft.Web.WebView2.Core.CoreWebView2NavigationStartingEventArgs) Handles webView2.NavigationStarting
webView2.AddScriptToExecuteOnDocumentCreated("
window.WebView2.addEventListener('beforenavigate', function(event) {
event.preventDefault();
var xhr = new XMLHttpRequest();
xhr.open(event.detail.verb, event.detail.uri, true);
xhr.setRequestHeader('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36');
xhr.setRequestHeader('Cache-Control', 'no-cache');
xhr.setRequestHeader('Accept-Encoding', 'gzip, deflate');
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
window.WebView2.injectWebResource(event.detail.id, xhr.responseText);
}
};
xhr.send();
});
")
End Sub
Am I using the rights methods?
edit1:
I've managed to add the UserAgent
Private Sub WebView21_NavigationStarting(sender As Object, args As Microsoft.Web.WebView2.Core.CoreWebView2NavigationStartingEventArgs) Handles WebView21.NavigationStarting
Dim userAgent As String = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36"
Dim script As String = $"window.navigator.userAgent = '{userAgent}';"
WebView21.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(script)
End Sub
but still it doesn't proceed after the login.

Chrome mobile emulation. Window size is different via Selenium and Devtools

Need to test web site responsibility.
Code example taken from here (in the bottom of page)
Faced, that selenium opens chrome window in different size/resolution, than i expect. Looks like that pixelRatio is not accepted or accepted incorrectly.
Also, faced, that in devtools, devices size from default device list is already divided on pixelRatio. e.g. Iphone 6 has 750 x 1334 and pixelRatio 2.0, but in devtools it is 375 x 667 which perfectly fits original resolution divided on pixelRatio. But if I manually add custom device 750 x 1334 with pixelRatio 2.0, it still shows me 750 x 1334
In source code Iphone 6 already defined with 'divided' size and pixelRatio 2.0
"title": "Apple iPhone 6",
"screen": {
"horizontal": {
"width": 667,
"height": 375
},
"device-pixel-ratio": 2,
"vertical": {
"width": 375,
"height": 667
}
Here is sample of my enum for mobile devices.
public enum ChromeMobileDevice {
IPHONE_8(1334, 750, 2.0, "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1"),
IPHONE_XS_MAX(2688, 1242, 3.0, "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/69.0.3497.105 Mobile/15E148 Safari/605.1"),
GALAXY_S8(2960, 1440, 4.0, "Mozilla/5.0 (Linux; Android 7.0; SM-G892A Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Mobile Safari/537.36"),
IPAD_MINI(2048, 1536, 2.0, "Mozilla/5.0 (iPad; CPU OS 12_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1"),
GALAXY_TAB_10_1(1920, 1200, 1.0, "Mozilla/5.0 (Linux; Android 8.1.0; SM-T580) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36");
private int height;
private int width;
private double pixelRatio;
private String userAgent;
private boolean touch = false;
private ChromeMobileDevice(int height, int width, double pixelRatio, String userAgent) {
this.height = height;
this.width = width;
this.pixelRatio = pixelRatio;
this.userAgent = userAgent;
}
public static ChromeMobileDevice getByName(final String chromeMobileDeviceName) {
return Stream.of(ChromeMobileDevice.values()).filter(b -> b.name().equalsIgnoreCase(chromeMobileDeviceName)).findAny()
.orElseThrow(() -> new IllegalArgumentException(String.format("Unsupported chrome emulator name: %s", chromeMobileDeviceName)));
}
public HashMap<String, Object> getPortraitDeviceMetrics() {
return Maps.newHashMap(ImmutableMap.of(
"height", height,
"width", width,
"pixelRatio", pixelRatio,
"touch", touch));
}
public HashMap<String, Object> getLandscapeDeviceMetrics() {
return Maps.newHashMap(ImmutableMap.of(
"width", height,
"height", width,
"pixelRatio", pixelRatio,
"touch", touch));
}
}
UPD
Sample of chromedriver creation
ChromeOptions capabilities = new ChromeOptions();
capabilities.setCapability("chrome.switches", "disable-extensions");
capabilities.setCapability(SUPPORTS_JAVASCRIPT, true);
capabilities.addArguments("--hide-scrollbars");
capabilities.addArguments("--allow-running-insecure-content");
capabilities.addArguments("--start-maximized");
capabilities.addArguments("--disable-infobars");
Map<String, Object> mobileEmulation = new HashMap<>();
ChromeMobileDevice chromeMobileDevice = ChromeMobileDevice.getByName(chromeMobileEmulation.get());
mobileEmulation.put("userAgent", chromeMobileDevice.getUserAgent());
mobileEmulation.put("deviceMetrics", chromeMobileDevice.getPortraitDeviceMetrics());
capabilities.setExperimentalOption("mobileEmulation", mobileEmulation);
WebDriver driver = new ChromeDriver(capabilities );

how to use fuel asynchronously in a kotlin jvm console app

I'm trying to use Fuel library to call some web-services asynchronously but the application process exits before the processing finishes.
Using sleep to delay exit is dumb, but I could not find a better way. Most of the examples show Fuel usage in a servlet or an android app.
Here is a sample.I used reqres to simulate a long-running service call.
import com.github.kittinunf.fuel.core.FuelManager
import com.github.kittinunf.fuel.httpGet
fun main(args: Array<String>) {
FuelManager.instance.baseHeaders = mapOf(
"User-Agent" to "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0"
)
"https://reqres.in/api/users?delay=3".httpGet().responseString { _, _, result ->
result.fold(
{ str ->
println("success")
},
{ fuelError ->
println("got error: $fuelError")
})
}
Thread.sleep(5_000)
println("main finishes")
}
Should I look into coroutines-style usage of Fuel or there is an easier way?

Using Selenium with Phantomjs in node not returning results

I have the following node route using selenium and chrome driver which is working correctly and returning expected html in the console:
app.get('/google', function (req, res) {
var driver = new webdriver
.Builder()
.forBrowser('chrome')
.build();
driver.get('https://www.google.com')
driver
.manage()
.window()
.setSize(1200, 1024);
driver.wait(webdriver.until.elementLocated({xpath: '//*[#id="lst-ib"]'}));
return driver
.findElement({xpath: '//*[#id="lst-ib"]'})
.sendKeys('stackoverflow' + webdriver.Key.RETURN)
.then((html) => {
return driver
.findElement({xpath: '//*[#id="rso"]/div[1]/div/div/div/div'})
.getAttribute("innerHTML")
})
.then((result) => {
console.log(result)
})
.then(() => {
res
.status(200)
.send('ok')
});
I have also installed the phantom js driver and tested that its working by returning the URL title - it works. When I use the above exact route and replace the chrome with phantomjs I get no results returned. There are no errors - just no print out in my console. The status and result are never sent to the browser so it doesn't appear to be stepping through promise chain.
Any suggestions?
The issue was that there was different html being rendered depending on the user agent. By forcing a user agent I was able to retrieve the results i needed.
Here is the code snippet replaced above to get this working.
.Builder()
// .forBrowser('phantomjs')
.withCapabilities(webdriver.Capabilities.phantomjs()
.set("phantomjs.page.settings.userAgent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"))
.build();

How to properly parse JSONP callback function in Meteor?

Does someone know how to parse JSONP callback in Meteor server methods?
I do
let response = HTTP.call('GET', AVIASALES_API_ENDPOINTS.getLocationFromIP, {
params: {
locale: 'en',
callback: 'useriata',
ip: clientIP
}
});
in response.content I’ve got
useriata({"iata":"MSQ","name":"Minsk","country_name":"Belarus"})
How to properly parse it?
It could help to know what you really try to accomplish? But here is a working example meteor actually doesn't do anything unusual with the requests.
Meteor.startup(function () {
var result = HTTP.call("GET", "https://api.github.com/legacy/repos/search/meteor", {
params: {},
headers: {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36"
}
});
console.log(result.data); // it's js object you can do result.data.repositories[0].name
console.log(JSON.stringify(result.data)); // json string
console.log(JSON.parse(JSON.stringify(result.data))) // if for some reason you need to parse it this way will work, but seems unnecessary
});
Update: The string you got back from the response wasn't valid JSON so you couldn't parse it used some regex to remove the invalid strings here is working example: http://meteorpad.com/pad/JCy5WkFsrtciG9PR5/Copy%20of%20Leaderboard