Categories
discuss

Switching to new window with Selenium/Protractor Javascript

Looking for some help on how I should be getting ahold of a new “pop-up” window that is triggered to display after I click a “login” button.

I am able to get to when the window is displaying but I do not believe that the code I am currently using to grab the window “handle” is working properly. My situation is a bit different in that I am using protractor inside my pages, but the new window comes up is NOT angular based, so I must switch over to using just selenium WebDriver while I am in that window. (Anyone have any idea if there could be issues with this approach?)

Below you can find the code snippet that I am using to create the selenium driver, as well as below that trying to “switch to / grab handle” of the new window that is popping up. I know that it is not working correctly because I keep receiving “No Such Element” errors in the code that follows trying to find a form on the page.

    // Create selenium webdriver / driver
    var webdriver = require('selenium-webdriver');

    var driver = new webdriver.Builder().
        withCapabilities(webdriver.Capabilities.chrome()).
        build();

  // Now make sure that the new window is popping up and we are navigating   correctly to it
      var handlePromise = browser.driver.getAllWindowHandles();
      handlePromise.then(function (handles) {
        // parentHandle = handles[0];
        var popUpHandle = handles[1];

        // Change to new handle
        browser.driver.switchTo().window(popUpHandle);

        var popUpHandleFinal = browser.driver.getWindowHandle();
        expect(popUpHandleFinal).toEqual(popUpHandle);
    });

Couple things about this:

  1. If I remove the “browser” in the line “browser.driver.switchTo().window(popUpHandle)” so it reads as “driver.switchTo().window(popUpHandle)” I receive back and error that reads as” UnknownError: unknown error: ‘name’ must be a nonempty string” After doing some searching on this it is because the “switchTo()” method on driver cannot be null. This error is cleared up if I just use the code shown above.

  2. I am not 100% sure if I should be using protractor (global “browser” var) or using the straight “driver” (Selenium) that I set before this as the way to get the windows.

Thank you for your help

Answer

As of latest version of Protractor (v2.2) there should not be an issue in using protractor window handles, which returns an array of windows that are currently being displayed. As P.T has pointed out there is no need to invoke a separate driver instance but a browser global variable will work. The window that invokes popup has array index of 0 and popup window will have an array index of 1. Below is a sample of switching to the pop up window to work on it.

browser.getAllWindowHandles().then(function(handles){
    browser.switchTo().window(handles[1]).then(function(){
        //do your stuff on the pop up window
    });
});

Hope this helps.

Categories
discuss

Why doesn’t chrome.tabs.query() return the tab’s URL when called using RequireJS in a Chrome extension?

I have a simple Chrome extension that adds a browser action. When the extension’s popup is opened, it needs to access the current tab’s URL. Since it doesn’t need access to all the tabs, I just have the activeTab permission specified in the manifest:

{
    "manifest_version": 2,
    "name": "RequireJS Test",
    "version": "0.0.1",
    "description": "Test RequireJS and the activeTab permission.",
    "permissions": [
        "activeTab"
    ],
    "browser_action": {
        "default_popup": "popup.html"
    },
    "web_accessible_resources": [
        "js/*",
        "html/*",
        "css/*",
        "img/*"
    ]
}

In theory, that should give the popup access to the active tab’s URL, but the URL is not returned when I query the tabs from within a require() call in the popup’s main.js file:

require([], function() {
    chrome.tabs.query({"active": true, "lastFocusedWindow": true}, function (tabs) {
        var url = tabs[0].url;
        console.log("URL from main.js", url);
    });

    console.log("URL from global var accessed in main.js", tabURL);
});

The console shows undefined for the URL. However, if I make the same call from a plain .js file that doesn’t use require(), it works fine:

chrome.tabs.query({"active": true, "lastFocusedWindow": true}, function (tabs) {
    tabURL = tabs[0].url;
    console.log("URL from get-url.js", tabURL);
});

That displays the correct URL, and I can access that global tabURL inside the require() call just fine. When I right-click the browser button and inspect the popup, the console output looks like this:

URL from get-url.js http://stackoverflow.com/questions/ask
URL from global var accessed in main.js http://stackoverflow.com/questions/ask
URL from main.js undefined

Even stranger is that I’ve sometimes seen the URL available from within that call to chrome.tabs.query() inside the require() call. But mostly it doesn’t work. Something about how RequireJS loads scripts seems to confuse Chrome and take away the URL access for the loaded script. This is in Chrome 40 on Windows.

Obviously, the workaround is to grab the URL in a separate script and store it in a variable, but that feels a bit kludgy. I’d like to see if there’s a proper way of getting this to work with RequireJS.

The full plugin source is here if anyone wants to test it on their machine: https://github.com/fwextensions/requirejs-url-test


Edit

As Rob W. explains below, this actually has nothing to do with RequireJS. The only reason that the code in my get-url.js file above returned the correct URL was that it happened to run before the devtools window opened. If I change that file to this:

setTimeout(function() {
chrome.tabs.query({"active": true, "lastFocusedWindow": true}, function (tabs) {
    tabURL = tabs[0].url;
    console.log("URL from get-url.js", tabURL);
});
}, 5000);

Then it runs after the devtools window is open and fails as well. RequireJS isn’t the culprit.

Answer

You don’t see a URL because you’ve only set the activeTab permission (not the tabs) permission AND the last focused window is the developer tools (for which you don’t have activeTab access) (and since Chrome 41, devtools tabs/windows are invisible to extensions, so tabs will be an empty array).

The good news is that this problem is specific to the devtools window being opened for your extension page, so the issue only occurs during development and not during actual use by users.

Extension popups are associated with a window, so you can use chrome.tabs.query with currentWindow:true to get the correct answer:

chrome.tabs.query({
    active: true,
    currentWindow: true
}, function(tabs) {
    var tabURL = tabs[0].url;
    console.log(tabURL);
});
Categories
discuss

Adding new value to existing Stream

Is there is a good way to add a new value to existing Stream? All I can imagine is something like this:

public <T> Stream<T> addToStream(Stream<T> stream, T elem ) {
    List<T> result = stream.collect(Collectors.toList());
    result.add(elem);
    return result.stream();
}

But I’m looking for something more concise that I can use in lambda expression without verbosity.

Another question appeared when I tried to implement PECS principle:

public <T> Stream<? super T> addToStream(Stream<? super T> stream, T elem ) {
    List<? super T> result = stream.collect(Collectors.toList()); //error
    result.add(elem);
    return result.stream();
}

Seems like wildcard doesn’t work with Stream.collect and I’m wondering why. Thanks in advance.

Answer

The question belies an incorrect assumption: that streams actually contain their data. They do not; streams are not data structures, they are a means for specifying bulk operations across a variety of data sources.

There are combinators for combining two streams into one, such as Stream.concat, and factories for creating streams from a set of known elements (Stream.of) or from collections (Collection.stream). So you can combine these if you want to produce a new stream that is the concatenation of the stream you have in hand, along with a new stream describing the new elements.

The problem in your PECS example is that you’ve got three occurrences of ? super T, and you are assuming they describe the same type, but they do not. Each occurrence of a wildcard corresponds to a unique capture, which isn’t what you want; you need to give that type variable a name so the compiler knows that the type of the list and the type of the input stream are the same. (Also, don’t materialize a collection; that’s expensive, and potentially non-terminating if the stream is not finite. Just use concat.) So the answer is: you just got the generics wrong. Here’s one way to do it:

public<T> Stream<T> appendToStream(Stream<? extends T> stream, T element) {
    return Stream.concat(stream, Stream.of(element));
}

You confused yourself with PECS because you were thinking about “inserting” into the stream, when in fact you’re consuming from it.

Categories
discuss

Eclipse – Change Console background color

I applied a theme for eclipse, where the Console’s background color is to dark.

If I want to change it by right clicking on the Console -> preferences -> background color the new Color doesnt get applied. Is there a way to apply a new BG Color even when using a theme?

Thanks!

Answer

I had a similar problem with luna. Didn’t work with the dark ‘theme’ and similar dark ‘color and font theme’ – had to reset to classic under main preferences. Then right clicking from within the console does change to the selected colour.
Maybe related to this recurring bug in eclipse.

Categories
discuss

Android Studio: Error: SplashActivity is not an Activity subclass or alias

I have a library project which has all functionality and some activities, and I also have a wrapper activity which only has a JSON configuration string and some styling. I imported the library to the wrapper project, and in the wrapper project I’m setting one of the library’s activities as the launch activity, but then get an error that the selected activity from the library is not an activity subclass or alias.

What does that mean and can I correct this?

The Activity that is supposed to be launched:

package dk.borgertip.activity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

import dk.borgertip.R;

public class SplashActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);

        Thread startTimer = new Thread() {
            @Override
            public void run() {
                try {
                    sleep(3000);
                    Intent i = new Intent(SplashActivity.this, MainActivity.class);
                    startActivity(i);
                    finish();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        startTimer.start();
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_splash, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

The project structure: (The Borgertip module is the library that contains the activity to launch which extends Activity)

The Borgertip module is the library that contains the activity to launch

The ‘Edit Configuration’ dialog with the error:

enter image description here

What do I do wrong?

Answer

You have to include the activity in your project AndroidManifest.xml

Source official doc:

In the manifest file of the application project, you must add declarations 
of all components that the application will use that are imported from a 
library project. For example, you must declare any <activity>, <service>, 
<receiver>, <provider>, and so on, as well as <permission>, 
<uses-library>, and similar elements.
Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..