Adding meta “viewport” for WordPress

Google recently changed their search algoritms to better recognize and weight “Mobile” support. This term is loosely defined in general, but to get your Google search “juice” you simply need to add a “viewport” meta tag. Unfortunately, unless you have the knowledge and want to edit your WordPress theme manually, there’s not an obvious way to add this.

Adding the “Definitely Allow Mobile Zooming” plugin makes this painless in WordPress without any additional configuration.

HTML code required (in <head>):

<meta name="viewport" content="width=device-width" />

PHP required (for manual addition):

<?php
function set_viewport() {
?>
<meta name="viewport" content="width=device-width" />
<?php
}
add_action('wp_head', 'set_viewport');
?>

REFERENCES:

HTTP Strict Transport Security (HSTS)

The HTTP Strict Transport Security feature lets a web site inform the browser that it should never load the site using HTTP, and should automatically convert all attempts to access the site using HTTP to HTTPS requests instead.

Example Use case:
If a web site accepts a connection through HTTP and redirects to HTTPS, the user in this case may initially talk to the non-encrypted version of the site before being redirected, if, for example, the user types http://www.foo.com/ or even just foo.com.

Problem:
This opens up the potential for a man-in-the-middle attack, where the redirect could be exploited to direct a user to a malicious site instead of the secure version of the original page.

Risk:
For HTTP sites on the same domain it is not recommended to add a HSTS header but to do a permanent redirect (301 status code) to the HTTPS site.

Bonus:
Google is always “tweaking” their search algorithms, and, at least at present time, gives greater weight to secure websites.


# Optionally load the headers module:
LoadModule headers_module modules/mod_headers.so

<VirtualHost *:443>
# Guarantee HTTPS for 1 Year including Sub Domains
Header always set Strict-Transport-Security "max-age=31536000; includeSubdomains; preload"
</VirtualHost>

Then you might (optionally, but recommended) force ALL HTTP users to HTTPS:

# Redirect HTTP connections to HTTPS
<VirtualHost *:80>
ServerAlias *
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
#RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [redirect=301]
</IfModule>
</VirtualHost>

That’s it…

REFERENCES:

meta viewport minimal-ui… a good idea in it’s time, just not useable…

Apple added this capability for fullscreen browser applications in Safari for IOS 7.1, unfortunately, they removed it in IOS 8.0


<meta name="viewport" content="width=device-width, minimal-ui" />

REFERENCES:

Using Ant to parse and download Maven pom.xml dependencies

I’ve migrated most of my projects to Maven, but occasionally have some developers that prefer to use Ant in their development environments. One problem that I used to have with Ant was that it required all dependencies to be checked into the SCM repository for each project. I recently found an Ant plugin that allows for it to read the Maven pom.xml and download the required dependencies, thus making projects MUCH easier to maintain! the steps are very simple.

Maven – pom.xml

  • Make sure that you have your dependencies (nexus?) setup and tested here.

Maven – global settings.xml

  • Make sure that your repositories are correctly configured.

Ant – build.xml (very minimal, I usually add as a step in existing scripts vs. using as standalone)

  • (example):

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <!DOCTYPE project>
    <project name="example" basedir="." default="dependencies" xmlns:artifact="antlib:org.apache.maven.artifact.ant">
    <taskdef uri="antlib:org.apache.maven.artifact.ant" classpath="ant/maven-ant-tasks-2.1.3.jar" />
    <target name="dependencies">
    <echo message="--- getting dependencies from maven pom.xml ---" />
    <artifact:pom id="pom" file="pom.xml" /><!-- settingsFile="settings.xml" -->
    <artifact:dependencies filesetId="test.dependencies" pomRefId="pom" useScope="test" />
    <copy todir="${antlib.dir}">
    <fileset refid="test.dependencies" />
    <mapper type="flatten" />
    </copy>
    </target>
    </project>
     
  • Make sure that you put the JAR (maven-ant-tasks-2.1.3.jar) in the proper place…

Executing:


  • ant dependencies

If everything is working well, you can now purge most of the JAR’s that reside inside your web projects as the Ant build process can retrieve them based on values in the Maven pom.xml file.

REFERENCES:
http://maven.apache.org/ant-tasks/examples/dependencies.html
http://maven.apache.org/ant-tasks/
http://search.maven.org/#artifactdetails%7Corg.apache.maven%7Cmaven-ant-tasks%7C2.1.3%7Cjar

Selenium Firefox modifyheaders

A few of my tests require access to modify the HTTP Request headers. Unfortunately, Selenium hides access to them to allow for portability, and to better emulate what “users” generally can change. To work around this a Firefox extension can be used and configured at runtime for this purpose.

NOTE: for Maven, you need to place a copy of the .xpi file referenced into the /src/test/resources folder for Selenium to locate it.

In the example below, I’m setting the HTTP Header for “DNT” to “1”.

public FirefoxDriver createFirefoxDriver() throws URISyntaxException, IOException {
// Specify the install location (if not default)
System.setProperty("webdriver.firefox.bin","C:\\path\\to\\Firefox.exe");
// Prevent Console log "noise" from the Selenium Firefox plugin
System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");
System.setProperty("org.apache.commons.logging.simplelog.log.httpclient.wire", "OFF");
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.commons.httpclient", "OFF");

final FirefoxProfile profile = new FirefoxProfile();
final URL url = this.getClass().getResource("/modify_headers-0.7.1.1-fx.xpi");
final File modifyHeaders = modifyHeaders = new File(url.toURI());

profile.setEnableNativeEvents(false);
profile.addExtension(modifyHeaders);

profile.setPreference("modifyheaders.headers.count", 1);
profile.setPreference("modifyheaders.headers.action0", "Add");
profile.setPreference("modifyheaders.headers.name0", "DNT");
profile.setPreference("modifyheaders.headers.value0", "1");
profile.setPreference("modifyheaders.headers.enabled0", true);
profile.setPreference("modifyheaders.config.active", true);
profile.setPreference("modifyheaders.config.alwaysOn", true);

final DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setBrowserName("firefox");
capabilities.setPlatform(org.openqa.selenium.Platform.ANY);
capabilities.setCapability(FirefoxDriver.PROFILE, profile);
return new FirefoxDriver(capabilities);
}

Take and save a screenshot capture with Selenium

As I recently discussed Selenium, it might be useful to know how to take screen captures during tests. I’ve found that putting the function into a java method makes usage a LOT easier… here are the relevant code bits (obviously this will not run on it’s own). Feel free to expand on it as needed as this is just a stub.


import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
/**
* @param driver {@code WebDriver}
* @param filename {@code String}
*/
protected static void takeScreenshot(final WebDriver driver, final String suffix){
final String fn = "takeScreenshot("+ driver.getCurrentUrl() +","+suffix+")";
final String filename = "/tmp/screenshot_" + suffix + ".png";

LOGGER.debug("takeScreenshot("+ driver.getCurrentUrl() +","+filename+")");
final File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// Now you can do whatever you need to do with it, for example copy somewhere
try{
FileUtils.copyFile(scrFile, new File(filename));
LOGGER.debug("[EXEC] {} {}",filename, fn);
}
catch(final IOException ex){
LOGGER.error("IOException:fn={},file={}:ex={}",fn,filename,ex);
}

}