2013

You are browsing the site archives for 2013.

I’m using Selenium for some browser-controlling stuff and mostly use Chrome with the ChromeDriver. But in Version 2.x, ChromeDriver only takes screenshots for the visible area of the screen.

So I created a Script in C# which scrolls around the page, taking screenshots and then stitches it all together.

The code should be easy to port into other languages.

// Get the Total Size of the Document
int totalWidth = (int)EvalScript("return document.width");
int totalHeight = (int)EvalScript("return document.height");

// Get the Size of the Viewport
int viewportWidth = (int)EvalScript("return document.body.clientWidth");
int viewportHeight = (int)EvalScript("return document.body.clientHeight");

// Split the Screen in multiple Rectangles
List rectangles = new List();
// Loop until the Total Height is reached
for (int i = 0; i < totalHeight; i += viewportHeight)
{
	int newHeight = viewportHeight;
	// Fix if the Height of the Element is too big
	if (i + viewportHeight > totalHeight)
	{
		newHeight = totalHeight - i;
	}
	// Loop until the Total Width is reached
	for (int ii = 0; ii < totalWidth; ii += viewportWidth)
	{
		int newWidth = viewportWidth;
		// Fix if the Width of the Element is too big
		if (ii + viewportWidth > totalWidth)
		{
			newWidth = totalWidth - ii;
		}

		// Create and add the Rectangle
		Rectangle currRect = new Rectangle(ii, i, newWidth, newHeight);
		rectangles.Add(currRect);
	}
}

// Build the Image
var stitchedImage = new Bitmap(totalWidth, totalHeight);
// Get all Screenshots and stitch them together
Rectangle previous = Rectangle.Empty;
foreach (var rectangle in rectangles)
{
	// Calculate the Scrolling (if needed)
	if (previous != Rectangle.Empty)
	{
		int xDiff = rectangle.Right - previous.Right;
		int yDiff = rectangle.Bottom - previous.Bottom;
		// Scroll
		RunScript(String.Format("window.scrollBy({0}, {1})", xDiff, yDiff));
		System.Threading.Thread.Sleep(200);
	}

	// Take Screenshot
	var screenshot = ((ITakesScreenshot)_driver).GetScreenshot();

	// Build an Image out of the Screenshot
	Image screenshotImage;
	using (MemoryStream memStream = new MemoryStream(screenshot.AsByteArray))
	{
		screenshotImage = Image.FromStream(memStream);
	}

	// Calculate the Source Rectangle
	Rectangle sourceRectangle = new Rectangle(viewportWidth - rectangle.Width, viewportHeight - rectangle.Height, rectangle.Width, rectangle.Height);

	// Copy the Image
	using (Graphics g = Graphics.FromImage(stitchedImage))
	{
		g.DrawImage(screenshotImage, rectangle, sourceRectangle, GraphicsUnit.Pixel);
	}

	// Set the Previous Rectangle
	previous = rectangle;
}
// The full Screenshot is now in the Variable "stitchedImage"

The EvalScript just executes the Javascript and returns the Value, so it should look like:

public override T EvalScript(string script)
{
	IJavaScriptExecutor js = (IJavaScriptExecutor)_driver;
	return (T)js.ExecuteScript(script);
}

Facebook provides a Like Box to show on your Website, what’s going on on your facebook page.

A nice way to show this box is by a simple tab on the left or right which (on mouseover) slides in this box.

Here’s an easy script to implement this on your page.

Following steps are needed to implement this:

1. Upload the Images for the Facebook Text-Logo
Image Left
Image Right

2. Add the jQuery Script to your page

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>

3. Add the CSS Styles

<style type='text/css'>
/*<![CDATA[*/
#fbplikebox {
	display: block;
	padding: 0;
	z-index: 99999;
	position: fixed;
}
.fbplbadgeright {
	background-color:#3B5998;
	display: block;
	height: 150px;
	top: 50%;
	margin-top: -75px;
	position: absolute;
	left: -47px;
	width: 47px;
	background-image: url('fbtext_right.png');
	background-repeat: no-repeat;
	overflow: hidden;
	-webkit-border-top-left-radius: 8px;
	-webkit-border-bottom-left-radius: 8px;
	-moz-border-radius-topleft: 8px;
	-moz-border-radius-bottomleft: 8px;
	border-top-left-radius: 8px;
	border-bottom-left-radius: 8px;
}
.fbplbadgeleft {
	background-color:#3B5998;
	display: block;
	height: 150px;
	top: 50%;
	margin-top: -75px;
	position: absolute;
	right: -47px;
	width: 47px;
	background-image: url('fbtext_left.png');
	background-repeat: no-repeat;
	overflow: hidden;
	-webkit-border-top-right-radius: 8px;
	-webkit-border-bottom-right-radius: 8px;
	-moz-border-radius-topright: 8px;
	-moz-border-radius-bottomright: 8px;
	border-top-right-radius: 8px;
	border-bottom-right-radius: 8px;
}
/*]]>*/
</style>

4. Add the Javascript

<script type='text/javascript'>
/*<![CDATA[*/
    (function(w2b){
        w2b(document).ready(function(){
			var fromRight = false;
			var topPosition = 50;
			var logoPosition = 150;
			var elementWidth = 292;
            var $dur = 'medium';
			
			// Set the Tab Position
			$("#fbplikeboxlogo").css("top", logoPosition);
			
			if (fromRight) {
				$("#fbplikeboxlogo").addClass("fbplbadgeright");
				w2b('#fbplikebox').css({right: -elementWidth, 'top' : topPosition })
				w2b('#fbplikebox').hover(function () {
					w2b(this).stop().animate({
						right: 0
					}, $dur);
				}, function () {
					w2b(this).stop().animate({
						right: -elementWidth
					}, $dur);
				});
			} else {
				$("#fbplikeboxlogo").addClass("fbplbadgeleft");
				w2b('#fbplikebox').css({left: -elementWidth, 'top' : topPosition })
				w2b('#fbplikebox').hover(function () {
					w2b(this).stop().animate({
						left: 0
					}, $dur);
				}, function () {
					w2b(this).stop().animate({
						left: -elementWidth
					}, $dur);
				});
			}
			w2b('#fbplikebox').show();
        });
    })(jQuery);
/*]]>*/
</script>

5. Add the Content

<div id='fbplikebox' style='display:none;'>
    <div id='fbplikeboxlogo'></div> 
	<iframe src="http://www.facebook.com/plugins/likebox.php?href=https%3A%2F%2Fwww.facebook.com%2FFacebookDevelopers&amp;width=292&amp;height=590&amp;colorscheme=light&amp;show_faces=true&amp;header=true&amp;stream=true&amp;show_border=true" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:292px; height:590px; background:#FFFFFF;" allowTransparency="true"></iframe>
</div>

There you go, that is all. Here’s a working examle:
facebookslide

There are some configuration variables at the top of the javascript:

Name Function
fromRight Defines if the tab is on the left or on the right
topPosition The space from the top of the page before the box starts
logoPosition The space from the top where the tab appears
elementWidth The width of the facebook box

Sometimes, you want to get the XPath of an element. Here are two working solutions, one in pure XSLT and one in C#.
Both of them return XPath in the form of: /html[1]/body[1]/div[1]/div[2]/div[3]/div[1]/p[2]/img[1]

C#

/// <summary>
/// Gets the X-Path to a given Node
/// </summary>
/// <param name="node">The Node to get the X-Path from</param>
/// <returns>The X-Path of the Node</returns>
public string GetXPathToNode(XmlNode node)
{
	if (node.NodeType == XmlNodeType.Attribute)
	{
		// attributes have an OwnerElement, not a ParentNode; also they have             
		// to be matched by name, not found by position             
		return String.Format("{0}/@{1}", GetXPathToNode(((XmlAttribute)node).OwnerElement), node.Name);
	}
	if (node.ParentNode == null)
	{
		// the only node with no parent is the root node, which has no path
		return "";
	}

	// Get the Index
	int indexInParent = 1;
	XmlNode siblingNode = node.PreviousSibling;
	// Loop thru all Siblings
	while (siblingNode != null)
	{
		// Increase the Index if the Sibling has the same Name
		if (siblingNode.Name == node.Name)
		{
			indexInParent++;
		}
		siblingNode = siblingNode.PreviousSibling;
	}

	// the path to a node is the path to its parent, plus "/node()[n]", where n is its position among its siblings.         
	return String.Format("{0}/{1}[{2}]", GetXPathToNode(node.ParentNode), node.Name, indexInParent);
}

XSLT

  <xsl:template name="GeneratePath">
	<xsl:param name="node" select="." />
	<xsl:message terminate="no">
	  <xsl:copy-of select="$node"/>
	</xsl:message>
	<xsl:apply-templates select="$node" mode="StartGeneratePath" />
  </xsl:template>

  <xsl:template match="*" mode="StartGeneratePath">
	<xsl:call-template name="genPath" />
  </xsl:template>
  
  <xsl:template name="genPath">
	<xsl:param name="prevPath"/>
	<xsl:variable name="currPath" select="concat('/',name(),'[',count(preceding-sibling::*[name() = name(current())])+1,']',$prevPath)"/>
	<xsl:for-each select="parent::*">
	  <xsl:call-template name="genPath">
		<xsl:with-param name="prevPath" select="$currPath"/>
	  </xsl:call-template>
	</xsl:for-each>
	<xsl:if test="not(parent::*)">
	  <xsl:value-of select="$currPath"/>
	</xsl:if>
  </xsl:template>

XSLT-Usage

<xsl:variable name="path">
  <xsl:call-template name="GeneratePath">
	<xsl:with-param name="node" select="./div[@class='eintrag2']//img[1]"/>
  </xsl:call-template>
</xsl:variable>

I’m currently writing an essay and I’ve got a lot ot tables in my word document. There are many ways to prevent cells, rows or tables to be splitted.
Here’s a list of the different possibilities:

Wenn man Tabellen oder nur einzelne Teile einer Tabelle vor unerwünschten Seitenumbrüchen schützen will, bieten sich folgende Einstellungen an:

  • Seitenumbruch in einer Zelle/Zeile verhindern: „Seitenwechsel in der Zeile zulassen“ deaktivieren (Tabelleneigenschaften > Reiter „Zeile“)
  • Seitenumbruch zwischen zwei Tabellenzeilen verhindern: „Absätze nicht trennen“ für die erste Tabellenzeile aktivieren (Format > Absatz > Reiter „Zeilen- und Seitenumbruch “)

Wenn mehrere Zeilen einer Tabelle auf einer Seite zusammen gehalten werden sollen, müssen mehrere, aufeinanderfolgende Zeilen mit dem Attribut „Absätze nicht trennen“ formatiert werden. Mit diesem Hilfsmittel lassen sich verschiedene Teile einer Tabelle auf einer Seite zusammen halten:

  • Die ganze Tabelle („Absätze nicht trennen“ für alle Zeilen außer der letzten)
  • Die ersten drei Zeilen nach der Tabellenkopfzeile („Absätze nicht trennen“ für die Tabellenkopfzeile und die nächsten beiden normalen Zeilen)
  • Die letzten drei Zeilen einer Tabelle („Absätze nicht trennen“ für die vor-vorletzte und vorletzte Tabellenzeile)
  • Die ganze Tabelle mit der Tabellenbeschriftung und der Quellenangabe („Absätze nicht trennen“ für alle Tabellenzeilen sowie den Absatz mit der Tabellenbeschriftung)

Wenn ein normaler Absatz vor der Tabelle, z.B. eine Tabellen-Beschriftung oder Tabellen-Überschrift mit der Tabelle zusammen halten sollen, muss auch für diesen Absatz „Absätze nicht trennen“ eingeschaltet werden.

Wenn ein normaler Absatz nach einer Tabelle mit der Tabelle (bzw. der letzten Tabellenzeile) zusammen gehalten werden soll, dann muss man für die letzte Tabellenzeile „Absätze nicht trennen“ einschalten.

Source

After some time, your TFS-Workspace can get quite crowded with files and folders which were deleted.

To clean your workspace and delete all unversioned files, navigate to a folder which is under source control and run the following command:
tfpt treeclean /exclude:*.suo,*.user /recursive
After some time, you’ll get a dialog which shows all files which will get deleted.

Sometimes after formatting a Harddrive and re-installing Windows, the NTFS-Permissions for other drives are kinda corrupted (need Admin-Rights for everything, “Unknown User” is there, …).

There is a simple command-line command you can execute to reset the permissions.

  1. Start “cmd” as Administrator
  2. Navigate to the Drive you want to reset the permissions
  3. Run the following command: icacls * /T /Q /C /RESET

After a while, your permissions are all fixed!

Source: http://lallousx86.wordpress.com/2009/06/14/resetting-ntfs-files-security-and-permission-in-windows-7/

More Info about icacls.exe