watir browser.attach overwrites previous browser object - watir

I need to test login using facebook connect on my site. When clicking on connect using facebook button, a pop is open.
I use ie = Watir::Browser.attach(:title, 'Login | Facebook') to assign this new window to a new object. But somehow it the previous browser object also refrences the new object.
b = Watir::Browser.start( "http://www.pstom.com" )
b.link(:text, "Connect with Facebook").click
irb(main):081:0> puts b.title
PSToM - Home
=> nil
ie = Watir::Browser.attach(:title, 'Login | Facebook')
puts b.title
Login | Facebook
=> nil
irb(main):085:0> puts ie.title
Login | Facebook
=> nil
What is going wrong (I'm testing in IRB in Ubuntu)

I think there was a problem with firewatir gem and attaching. Try the same with watir-webdriver gem (it can drive Firefox).
github: https://github.com/jarib/watir-webdriver
rubygems: https://rubygems.org/gems/watir-webdriver
installation:
https://github.com/zeljkofilipin/watirbook/blob/master/installation-ubuntu.md
https://github.com/zeljkofilipin/watirbook/downloads

I got the correct behavior on Windows/IE. What versions do you have? I have ruby 1.8.7 and watir 1.7.1
irb(main):001:0> require 'watir'
=> true
irb(main):002:0> a = Watir::Browser.attach(:title, 'Google')
=> #<Watir::IE:0x4ecfde0 url="http://www.google.com/" title="Google">
irb(main):003:0> puts a.title
Google
=> nil
irb(main):004:0> b = Watir::Browser.attach(:title, 'Bing')
=> #<Watir::IE:0x4ea59d8 url="http://www.bing.com/" title="Bing">
irb(main):005:0> puts b.title
Bing
=> nil
irb(main):006:0> puts a.title
Google
=> nil
irb(main):007:0>

Related

Does Instagram Reels have an API for developers?

I cannot find an Instagram Reels related API. Does anyone know if there is one or if there will be one?
Currently the Facebook developer documentation does not mention anything about Instagram Reels.
https://developers.facebook.com/docs/instagram-api/overview/
UPDATED ANSWER:
Reels are now supported via the API; it became generally available on July 6, 2022. Please see https://developers.facebook.com/blog/post/2022/06/27/introducing-reels-apis-to-instagram-platform/.
ORIGINAL ANSWER:
In the Instagram API docs, under Limitations, it currently says "Reels are not supported."
Reels it is IG Media with type "VIDEO".
And you can fetch single "Reels" if you know his Facebook Media ID (It is not Media ID from instagram)
If reels published like stories you can get media's list from stories endpoint(GET graph.facebook.com/{ig-user-id}/stories). You will get array of medias' ids.
"data": [
{
"id": "{ig-media-id}"
},
...
]
}
Then you can fetch information from single media object endpoint (GET /{ig-media-id})
So at current moment you can get reels by api only if they published like story.
Anyway reels is not supported in some countries and you can see reels only from stories in this countries.
UPDATE
Reels also available when you fetch user media from business-discovery(GET {ig-user-id}?fields=business_discovery.username(instagramm_user_name){media{id,permalink,media_type,media_url}}
) or user media (GET /{ig-user-id}/media).
If media's permalink look likes https://www.instagram.com/reel/... and media_type VIDEO then is it reels.
Not sure, but I did some digging around an Instagram .ipa file and found these url scheme parameters.
instagram://reels_home
instagram://reels_share
Both of which if clicked on ios will take you to the reels feed. My intentions are to open the reels camera (or the story camera with the mode set to reels), but i guess currently we can only access the reels feed.
It seems they were included in the GET /{ig-user-id}/media and the GET {ig-user-id}?fields=business_discovery.username(instagramm_user_name) endpoints at the beginning but they removed them later. According to the docs they are not supported at the moment. Further confirmed in this bug report. It seems it is not the first time they include nodes that are not supposed to be included (IGTV and now reels).
Naa,
Instagram doesn't provide any API for Reels yet, since the reel feature is still not available in many countries but this going to be available soon.
So the question arises here, how we can get the reels data via API?
Well, the answer is you can't But! if you are in favour to do so some scraping thing then the answer is definitely Yes!
But How?
We all know scraping has lots of efforts, due to things get changed very frequent. and if you don't care about those below are sample PHP script to fetch reels data in JSON.
<?php
//!IMPORTANT
$sessionid = ["Cookie: sessionid=YOUR SESSION ID HERE"];
// REELS SHORT CODE FROM URL
$shortcode = null;
$response = [];
/**
* Get a web file (HTML, XHTML, XML, image, etc.) from a URL. Return an
* array containing the HTTP server response header fields and content.
*/
function get_web_page($url)
{
$user_agent = 'Mozilla/5.0 (Windows NT 6.1; rv:8.0) Gecko/20100101 Firefox/8.0';
$options = array(
CURLOPT_CUSTOMREQUEST => "GET", //set request type post or get
CURLOPT_POST => false, //set to GET
CURLOPT_USERAGENT => $user_agent, //set user agent
# CURLOPT_COOKIEFILE => "cookie.txt", //set cookie file
# CURLOPT_COOKIEJAR => "cookie.txt", //set cookie jar
CURLOPT_HTTPHEADER => $sessionid, // sending manually set cookie
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_HEADER => false, // don't return headers
CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_ENCODING => "", // handle all encodings
CURLOPT_AUTOREFERER => true, // set referer on redirect
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
CURLOPT_TIMEOUT => 120, // timeout on response
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
);
$ch = curl_init($url);
curl_setopt_array($ch, $options);
$content = curl_exec($ch);
$err = curl_errno($ch);
$errmsg = curl_error($ch);
$header = curl_getinfo($ch);
curl_close($ch);
$header['errno'] = $err;
$header['errmsg'] = $errmsg;
$header['content'] = $content;
return $header;
}
if ((isset($_GET['q'])) && !empty($_GET['q'])) {
$shortcode = $_GET['q'];
$reels_url = "https://www.instagram.com/p/$shortcode/?__a=1";
// read a web page and check for errors:
$result = get_web_page($reels_url);
if ($result['errno'] != 0) {
$response = json_encode(['error' => "bad url, timeout, redirect loop"]);
}
if ($result['http_code'] != 200) {
$response = json_encode(['error' => "no page, no permissions, no service"]);
}
if ($result['http_code'] === 200) {
$response = $result['content'];
}
}
// JSON OUTPUT OR ERROR HERE
header('Content-Type: application/json');
echo $response;
How to use this PHP script?
Save the above script in a PHP file e.g. fetch-reels.php and run it like
http://localhost/fetch-reels.php?q={SHORT-CODE}
Reels URL e.g.
https://www.instagram.com/p/COlKxQLAM11
https://www.instagram.com/reel/COlKxQLAM11/?igshid=12f6j9a1dfx2x
As mentioned earlier Instagram doesn't provide direct apis but you can take help of Instagrapi its really awesome and easy to use. Note : This Instagram Private API wrapper is in python.
Here's how to use it -
Install the lib :
python -m pip install instagrapi
Code
from instagrapi import Client
cl = Client()
#enter your username and password
cl.login('username', 'password')
#you can replace 10 with whatever amount of reels you want to fetch
reel = cl.explore_reels(amount = 10)
print(reel)
That's it !!!
Instagram just released reels support (Available to everyone from July 7th 2022).
More here
https://developers.facebook.com/docs/instagram-api/guides/content-publishing/
Instagram Reels API is now generally available:
https://developers.facebook.com/blog/post/2022/06/27/introducing-reels-apis-to-instagram-platform/
You can make a scheduled post. For example using JavaScript and uploading a video to the Reels API[1]:
const access_token = "Js82ks92jald"; // The access token given from FB
const instagram_user_id = "12345"; // The IG user's ID
const reelUrl = "https://www.website.com/reel.mp4";
const caption = "This is the best real ever #Reels4Real";
const postUrl = `https://graph.facebook.com/${instagram_user_id}/media?video_url=${encodeURIComponent(reelUrl)}&caption=${encodeURIComponent(caption)}&access_token=${access_token}&media_type=REELS&share_to_feed=true&thumb_offset=2000`;
const postOptions = {
method: "POST",
headers: {
"Content-Type": "application/json",
},
};
fetch(postUrl, postOptions)
.then((res) => res.json())
.then(json => console.log(json))
.catch(console.error);
Note the key fields of media_type=REELS, video_url, and caption.
[1] https://www.ayrshare.com/instagram-reels-api-how-to-post-videos-to-reels-using-a-social-media-api/
Update (14-July-2022): Meta (Facebook) launched support for Reels via their official Graph API. Read more about it here: https://developers.facebook.com/docs/instagram-api/reference/ig-user/media#reel-specifications
Meta just release Reels API for the Instagram Platform.
https://developers.facebook.com/blog/post/2022/06/27/introducing-reels-apis-to-instagram-platform/

custom function to form a url to download a document based on key

i am using integrated document server 4.4.3 ubuntu based, bellow code is customized for my suitability, how can i form a url based on key
asc_docs_api.prototype.asc_customCallback = function(typeFile, bIsDownloadEvent)
{
var actionType = c_oAscAsyncAction.DownloadAs;
var options = {downloadType : DownloadType.Download };
this._downloadAs("save", typeFile, actionType, options, function(incomeObject){
if (null != incomeObject && "save" == incomeObject["type"]) {
//incomeObject["data"] will return key of the document instead of key, i need full url of the document with md5 and expires like below
//ex: http://cache/files/.....
});
};
thank you in advance
You are trying to get the link too early, the file is not yet available, the conversion process might not be completed.
This callback only means that the conversion task is created
But you can try using the function onDownloadAs (created for the integrators who are going to create external button downloadAs)
http://api.onlyoffice.com/editors/config/events#onDownloadAs
A link to the file will be sent to:
asc_docs_api.prototype.processSavedFile = function(url, downloadType)

Code renders in browser but errors in the IBM Notes client

I have two computed fields and want update them. It works great in the browser, but the IBM Notes client gives an error.
Here is the code:
var Admin = #DbColumn("", "GoreAdmins", 1);
var AdminBackup = #DbColumn("", "GoreAdmins", 2);
if (Admin && typeof Admin == "string") Admin = new Array(Admin);
if (AdminBackup && typeof AdminBackup == "string") AdminBackup = new Array(AdminBackup);
if (document1.isNewNote()) {
document1.setValue("Admin", Admin);
document1.setValue("AdminBackup", AdminBackup);
};
I get the error on this line:
document1.setValue("Admin", Admin);
The first parameter for #DbColumn() and #DbLookup needs to be the database, easiest done with #DbName(). The method of passing a blank string won't work in XPiNC. It's standard for Notes Client development, works for XPages on a browser but is bad practice for this very reason.

page object watir cucumber test for file being downloaded

I'm trying to test that a file downloaded is initialized when i click on an image. So far i've been unable to find anything that seems to work with page object.
More specifically i'm looking for a way to handle the download dialogue pop up and to verify that file.exe has begun downloading.
Thank you
You can activate some option when you launch your browser. Here an example I use :
# create the folder location
download_directory = "#{Dir.pwd}/downloads/"
download_directory.gsub!("/", "\\") if Selenium::WebDriver::Platform.windows?
# Create the firefox profile
profile['browser.download.folderList'] = 2
profile['browser.download.dir'] = download_directory
profile['download.prompt_for_download'] = false
profile['browser.helperApps.neverAsk.saveToDisk'] = "application/octet-stream,text/csv,application/pdf"
profile['network.http.use-cache'] = false
# launch FF
#browser = Watir::Browser.new :firefox, profile: profile
Then you don't need to handle the window, but only to check the downloaded file in the folder you define.
For chrome, you can't use a profile, but should use preferences.
# Create the prefs
prefs = {
download: {
prompt_for_download: false,
default_directory: #download_directory
}
}
# Launch chrome
#browser = Watir::Browser.new :chrome, prefs: prefs
And no, I don't find a solution for internet explorer yet.

Issue getting user/password with GetAuthenticationInfo in firebreath

I'm trying to get user/password from Firebreath plugin with the use of NpapiBrowserHost.GetAuthenticationInfo method.
I need to do this for npapi based browsers (chrome / firefox / opera). So this is my code:
boost::shared_ptr<FB::Npapi::NpapiBrowserHost> npapihost =
FB::ptr_cast<FB::Npapi::NpapiBrowserHost>(m_host);
if(npapihost)
{
char * username = NULL; uint32_t ulen = 0;
char * password = NULL; uint32_t plen = 0;
NPError err = npapihost->GetAuthenticationInfo("http",
"xxx.yyy.com",
80,
"Basic",
"Knownnameofrealm",
&username, &ulen,
&password, &plen );
}
In Opera it works. In Chrome & Firefox it returns err = NPERR_GENERIC_ERROR,
and ulen = 0, plen = 0 (username, password - bad ptr).
This code is executed from MypluginamePlugin::onPluginReady().
If you succeeded in getting credentials, please post code example.
PS Chrome according to chromium sources does not yet implement NPN_GetAuthenticationInfo https://code.google.com/p/chromium/issues/detail?id=23928
In Firefox I should use -1 instead of 80 for http (443 for https).
Simply speaking FF's password managing service stored all it's info inside a hashmap:
Map entry = ( (key to auth. object) , (objects with single user auth. info) )
Each key is a string created as follows: (some pro stuff) + (scheme) + "://" + (host) + ":" + (port).
FF substituted INTERNET_DEFAULT_HTTP_PORT = 80 (INTERNET_DEFAULT_HTTPS_PORT = 443) with -1 while creating new map entry.
In Opera initially all worked fine.
In Chrome browser-side endpoint function is not implemented since stub creation at 2009.
In IE npapihost is not available. Although I didn't even have to mess with login/password extraction because default CInternetSession (wininet package) constructor does it automatically.

Resources