Testing excel with Winappdriver - excel

Where can i find a good example of testing an excel addin project with custom ribbon elements, using winappdriver.
What i have so far throws an exception:
System.InvalidOperationException
An element could not be located on the page using the given search parameters.
I am using latest winappdriver
Code:
private const string ExcelAppId = #"C:\Program Files (x86)\Microsoft Office\root\Office16\EXCEL.EXE";
private const string WindowsApplicationDriverUrl = "http://127.0.0.1:4723";
DesiredCapabilities appCapabilities = new DesiredCapabilities();
appCapabilities.SetCapability("app", ExcelAppId);
appCapabilities.SetCapability("deviceName", "WindowsPC");
appCapabilities.SetCapability("platformName", "Windows");
session = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), appCapabilities);
session.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
session.FindElementByName("Blank workbook").Click();

I'm working on automated testing of an Excel add-in with WinAppDriver.
In my case I started Excel without the splash screen. Supply /e as app parameter to achieve it.
session.SetCapability("appArguments", "/e");
From this point onward, you'll be able to find the "File" menu and "New" menu by name and click them.
Add a few seconds of explicit wait and proceed to finding "Blank Workbook" WindowsElement the same way.
I hope this answers your question, post here if more help is needed.
I've been experimenting with WinAppDriver for a few months now, also preparing a Udemy course on the subject which is almost ready to publish. It's an interesting toolkit.

You need to install Appium.WebDriver, Selenium.support, Selenium.webDriver from "Manage Nuget packages"
you can use appium code like:
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Windows;
class Excel
{
public void ExcelCase() {
WindowsDriver<WindowsElement> driver;
AppiumOptions desiredcap = new AppiumOptions();
desiredcap.AddAdditionalCapability("app", #"C:\Program Files\Microsoft Office\Office16\EXCEL.EXE");
driver = new WindowsDriver<WindowsElement>(new Uri("http://127.0.0.1:4723"), desiredcap);
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
if (driver == null)
{
Console.WriteLine("App not running");
return;
}
}}
Try this code and comment if you face any issue.

I prefer to use: session.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5); instead of Thread.sleep(5).

Does it even open the excel when you start the test?
If by Name is not working, it doens't work to me sometimes either, you can use the accessibilityId
session.FindElementByAccessibilityId("AIOStartDocument").Click();
or use the keyboard shorcut to open the blank workbook, like this:
session.Keyboard.SendKeys(Keys.Alt + "f" + "l" + Keys.Alt);

Related

How to Re-enable a disabled excel addin from vbs [duplicate]

I am trying to create a new instance of Excel using VBA using:
Set XlApp = New Excel.Application
The problem is that this new instance of Excel doesn't load all the addins that load when I open Excel normally...Is there anything in the Excel Application object for loading in all the user-specified addins?
I'm not trying to load a specific add-in, but rather make the new Excel application behave as though the user opened it themself, so I'm really looking for a list of all the user-selected add-ins that usually load when opening Excel.
I looked into this problem again, and the Application.Addins collection seems to have all the addins listed in the Tools->Addins menu, with a boolean value stating whether or not an addin is installed. So what seems to work for me now is to loop through all addins and if .Installed = true then I set .Installed to False and back to True, and that seems to properly load my addins.
Function ReloadXLAddins(TheXLApp As Excel.Application) As Boolean
Dim CurrAddin As Excel.AddIn
For Each CurrAddin In TheXLApp.AddIns
If CurrAddin.Installed Then
CurrAddin.Installed = False
CurrAddin.Installed = True
End If
Next CurrAddin
End Function
Using CreateObject("Excel.Application") would have the same result as using New Excel.Application, unfortunately.
You will have to load the Addins that you need individually by file path & name using the Application.Addins.Add(string fileName) method.
I'm leaving this answer here for anyone else who ran into this problem, but using JavaScript.
A little background... In my company we have a 3rd party web app that used JavaScript to launch Excel and generate a spreadsheet on the fly. We also have an Excel add-in that overrides the behavior of the Save button. The add-in gives you the option of saving the file locally or in our online document management system.
After we upgraded to Windows 7 and Office 2010, we noticed a problem with our spreadsheet-generating web app. When JavaScript generated a spreadsheet in Excel, suddenly the Save button no longer worked. You would click save and nothing happened.
Using the other answers here I was able to construct a solution in JavaScript. Essentially we would create the Excel Application object in memory, then reload a specific add-in to get our save button behavior back. Here's a simplified version of our fix:
function GenerateSpreadsheet()
{
var ExcelApp = getExcel();
if (ExcelApp == null){ return; }
reloadAddIn(ExcelApp);
ExcelApp.WorkBooks.Add;
ExcelApp.Visible = true;
sheet = ExcelApp.ActiveSheet;
var now = new Date();
ExcelApp.Cells(1,1).value = 'This is an auto-generated spreadsheet, created using Javascript and ActiveX in Internet Explorer';
ExcelApp.ActiveSheet.Columns("A:IV").EntireColumn.AutoFit;
ExcelApp.ActiveSheet.Rows("1:65536").EntireRow.AutoFit;
ExcelApp.ActiveSheet.Range("A1").Select;
ExcelApp = null;
}
function getExcel() {
try {
return new ActiveXObject("Excel.Application");
} catch(e) {
alert("Unable to open Excel. Please check your security settings.");
return null;
}
}
function reloadAddIn(ExcelApp) {
// Fixes problem with save button not working in Excel,
// by reloading the add-in responsible for the custom save button behavior
try {
ExcelApp.AddIns2.Item("AddInName").Installed = false;
ExcelApp.AddIns2.Item("AddInName").Installed = true;
} catch (e) { }
}

How execute a combination key on node-webkit like c# sendkeys

I made a Webkit app that register small codes on txt like snippets to use later on other apps. I can find my "snippet" and set the content on clipboard.
But also , I would like run "Ctrl+v" keys combination on Node-Webkit like the SendKeys function on C#.
Now I need press manually keys combination "Ctrl+v" to paste in another app.
Also i was thinking how run another file like a small exe program that do it the SendKey function and close it. But I prefer a node-webkit function without call other script or exe program.
It ´s posible to do it , and How can i do it ? Thanks guys.
Well, I was looking for an answer on the Internet without results.
But the best solution i 've implemented is to use a VBScript help file .
And it works well !!
The app calls the Paste function to execute the " paste.vbs " file.
paste.vbs
set shell = CreateObject("WScript.Shell")
WScript.Sleep 300
shell.SendKeys "^V"
myapp.js
var gui = require('nw.gui');
var win = gui.Window.get();
function getCommandLine() {
switch (process.platform) {
case 'darwin' : return 'open';
case 'win32' : return 'start';
case 'win64' : return 'start';
default : return 'xdg-open';
}
}
function Paste(){
var sys = require('util');
var exec = require('child_process').exec;
exec(getCommandLine() + ' ' + "paste.vbs");
}
function useSnippet(content){
var clipboard = gui.Clipboard.get();
clipboard.set(content, 'text');
win.minimize();
Paste();
}
Now you can get the file contents for pasting into other applications.
If you want compatibility with other operating systems, you must use another command file similar to VBS
I use a list of files and reading passages content of a search list .
I can create a project on GitHub to load the code so that other people can use it or help me improve the code.

Convert CSV to Excel Windows Phone 8

with windows phone 8 I need to be able to open a CSV file in Excel using C#. Their is an app on the market now called Excel Extensions that converts the csv file locally.
I have tired converting the CSV file using open office XML but that didn't work. and I want to do it locally so no web services.
Anyone know how I can convert the CSV file to Excel on the Windows Phone 8 platform?
THEORY
You have a two distinct options: (1) doing most of the work on the WP8 client (2) or doing most of the work on a remote server.
For option #2 of using a remote server: Expose a WCF service that takes in the CSV file, parses the CSV to find its logical 2D table structure, use ClosedXML to save a new XLSX file and return that to the client. This option is the most straightforward but also requires network connectivity and a hosted server.
For option #1 of not using a remote server: read the CSV file, copy the CSV data into to an XLSX file, save the XLSX into IsoStore and launch excel with that file. I've written about this topic in the past # How can we create, write and read an excel file for Windows Phone 8
One thing you'll have to do quite a lot of work is writing a XLSX file in pure WP7 C#. You'll either have to convert 3rd party libraries that write XLSX to support WP7/WP8, or convert simple end-to-end C# code samples to WP7/WP8. Both aren't simple. Converting ClosedXML is possible but DocumentFormat.OpenXml's dependency on WPF's WindowsCore is a problem. Another option is to write your own OpenXML C# implementation like Chris Klug did here for Word OpenXML on Silverlight and was ported to WP7 later on. The key is using OpenXML specification for your advantage.
LIVE CODE SAMPLE
For example, looking at Chris Klug's Silverlight Excel OpenXML article it's possible to take his code for Ag.OpenXML and OpenXML.Silverlight.Spreadsheet port those to WP8 and then simply invoke them. I did just that. Here's how to get that experimental source code and get started:
1) Download and unzip # http://JustinAngel.net/Storage/OpenXML.Silverlight.Spreadsheet.WP8.zip
2) Add a reference to the csproj, or to the DLLs OpenXML.Silverlight.Spreadsheet.WP8.dll & SharpZipLib.dll from "OpenXML.Silverlight.Spreadsheet.WP8\Bin\Debug".
3) Add the following code snippet that saves a SpreedsheetDocument file into your app's WP8 IsoStore and then launches it in Word using WP8 app2app file associations.
private async void SaveXlsxToIsoStoreAndLaunchInExcel(SpreadsheetDocument doc)
{
using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
if (isoStore.FileExists("myFile.xlsx"))
isoStore.DeleteFile("myFile.xlsx");
using (var s = isoStore.CreateFile("myFile.xlsx"))
using (IStreamProvider storage = new ZipStreamProvider(s))
{
doc.Save(storage);
}
Launcher.LaunchFileAsync(
await ApplicationData.Current.LocalFolder.GetFileAsync("myFile.xlsx"));
}
}
4) Invoke the above code snippet with Chris's sample document:
private async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
SpreadsheetDocument doc = new SpreadsheetDocument();
doc.ApplicationName = "SilverSpreadsheet";
doc.Creator = "Chris Klug";
doc.Company = "Intergen";
SharedStringDefinition str1 = doc.Workbook.SharedStrings.AddString("Column 1");
SharedStringDefinition str2 = doc.Workbook.SharedStrings.AddString("Column 2");
SharedStringDefinition str3 = doc.Workbook.SharedStrings.AddString("Column 3");
doc.Workbook.Sheets[0].Sheet.Rows[0].Cells[0].SetValue(str1);
doc.Workbook.Sheets[0].Sheet.Rows[0].Cells[1].SetValue(str2);
doc.Workbook.Sheets[0].Sheet.Rows[0].Cells[2].SetValue(str3);
doc.Workbook.Sheets[0].Sheet.Rows[1].Cells[0].SetValue("Value 1");
doc.Workbook.Sheets[0].Sheet.Rows[1].Cells[1].SetValue(1);
doc.Workbook.Sheets[0].Sheet.Rows[1].Cells[2].SetValue(1001);
doc.Workbook.Sheets[0].Sheet.Rows[2].Cells[0].SetValue("Value 2");
doc.Workbook.Sheets[0].Sheet.Rows[2].Cells[1].SetValue(2);
doc.Workbook.Sheets[0].Sheet.Rows[2].Cells[2].SetValue(1002);
doc.Workbook.Sheets[0].Sheet.Rows[3].Cells[0].SetValue("Value 3");
doc.Workbook.Sheets[0].Sheet.Rows[3].Cells[1].SetValue(3);
doc.Workbook.Sheets[0].Sheet.Rows[3].Cells[2].SetValue(1003);
doc.Workbook.Sheets[0].Sheet.Rows[4].Cells[0].SetValue("Value 4");
doc.Workbook.Sheets[0].Sheet.Rows[4].Cells[1].SetValue(4);
doc.Workbook.Sheets[0].Sheet.Rows[4].Cells[2].SetValue(1004);
TablePart table = doc.Workbook.Sheets[0].Sheet.AddTable("My Table", "My Table", doc.Workbook.Sheets[0].Sheet.Rows[0].Cells[0], doc.Workbook.Sheets[0].Sheet.Rows[4].Cells[2]);
table.TableColumns[0].Name = str1.String;
table.TableColumns[1].Name = str2.String;
table.TableColumns[2].Name = str3.String;
doc.Workbook.Sheets[0].Sheet.AddColumnSizeDefinition(0, 2, 20);
doc.Workbook.Sheets[0].Sheet.Rows[5].Cells[1].SetValue("Sum:");
doc.Workbook.Sheets[0].Sheet.Rows[5].Cells[2].Formula = "SUM(" + doc.Workbook.Sheets[0].Sheet.Rows[1].Cells[2].CellName + ":" + doc.Workbook.Sheets[0].Sheet.Rows[4].Cells[2].CellName + ")";
SaveXlsxToIsoStoreAndLaunchInExcel(doc);
}
5) When running this code snippet we can see the following warning popup and then the excel spreadsheet. Feel free to improve upon my hasty Silverlight-->WP8 port and remove that warning.

Excel process stays alive even after calling Quit

I am creating Excel Sheet using Devexpress Exporter and then saving the file at a particular location.
After the creation of file, I have to open it, to add dropdownlist of items and then save it again in same location.
After all the operations, the file has to be emailed automatically to the email address from database.
Now if I have 1000 email addresses, and to automate this process, it is creating more than 10 instances of Excel.
How can I stop creation of those instance and how can I use excel operations without using more memory.
Code is as below:
protected string CreateExcelFile(string FilterName)
{
Random ranNumber = new Random();
int number = ranNumber.Next(0, 10000000);
string FileName = "TestDoc"+DateTime.Now.Year.ToString()+number.ToString()+DateTime.Now.Second.ToString()+".xls";
string path = #"c:\TestDocuments\"+FileName;
Directory.CreateDirectory(Path.GetDirectoryName(path));
FileStream fs = new FileStream(path, FileMode.OpenOrCreate);
XlsExportOptions options = new XlsExportOptions();
options.ExportHyperlinks = false;
ASPxExporter.WriteXls(fs, options);
fs.Close();
AddDropDownToExcel(path);
return path;
}
//Adding The Dropdownlist Of Items TO Generated Excel Sheet
protected void AddDropDownToExcel(string path)
{
Microsoft.Office.Interop.Excel.Application application = new Microsoft.Office.Interop.Excel.Application();
string fileName = path.Replace("\\", "\\\\");
string RowCount = "F" + (testgrid.VisibleRowCount + 1).ToString();
// Open Excel and get first worksheet.
var workbook = application.Workbooks.Open(fileName);
var worksheet = workbook.Worksheets[1] as Microsoft.Office.Interop.Excel.Worksheet;
// Set range for dropdownlist
var rangeNewStatus = worksheet.get_Range("F2", RowCount);
rangeNewStatus.ColumnWidth = 20;
rangeNewStatus.Validation.Add(Microsoft.Office.Interop.Excel.XlDVType.xlValidateList, Microsoft.Office.Interop.Excel.XlDVAlertStyle.xlValidAlertStop,
Microsoft.Office.Interop.Excel.XlFormatConditionOperator.xlBetween, "Item1,Item2,Item3,Item4");
// Save.
workbook.Save();
workbook.Close(Microsoft.Office.Interop.Excel.XlSaveAction.xlSaveChanges, Type.Missing, Type.Missing);
application.Quit();
}
First, I sincerely hope this isn't running on a server.
Then, if your problem is that too many instances of Excel are created, a thought is "don't create an instance every single time". Instead of starting Excel every time AddDropDownToExcel is called, can you reuse the same instance?
The problem you are having shows up regularly in Excel interop scenario; even though you are done and tell Excel to close, it "stays alive". It's usually caused by your app still holding a reference to a COM object that hasn't been disposed, preventing Excel from closing. This StackOverflow answer provides some pointers: https://stackoverflow.com/a/158752/114519
In general, to avoid that problem, you want to follow the "one-dot" rule. For instance, in your code:
var workbook = application.Workbooks.Open(fileName);
will be a problem, because an "anonymous" wrapper for Workbooks is created, and will likely not be disposed properly. The "one-dot" rule would say "don't use more than one dot when working with Excel interop", in this case:
var workbooks = application.Workbooks;
var workbook = workbooks.Open(fileName);
A totally different thought - instead of using Interop, can't you use OpenXML to generate your Excel file? I have never tried it to create drop downs, but if it supports it, it will be massively faster than Interop, and the type of problems you have won't happen.
Hope this helps.
As I know the grow of number of runnig excel.exe processes is 'normal' situation to excel :)
The dumbest advice is just kill sometimes it's processes. BUT, this way will be absolutely unhelpful if you use excel during your app is working because of you rather don't get which one excel.exe is yours.

Loading addins when Excel is instantiated programmatically

I am trying to create a new instance of Excel using VBA using:
Set XlApp = New Excel.Application
The problem is that this new instance of Excel doesn't load all the addins that load when I open Excel normally...Is there anything in the Excel Application object for loading in all the user-specified addins?
I'm not trying to load a specific add-in, but rather make the new Excel application behave as though the user opened it themself, so I'm really looking for a list of all the user-selected add-ins that usually load when opening Excel.
I looked into this problem again, and the Application.Addins collection seems to have all the addins listed in the Tools->Addins menu, with a boolean value stating whether or not an addin is installed. So what seems to work for me now is to loop through all addins and if .Installed = true then I set .Installed to False and back to True, and that seems to properly load my addins.
Function ReloadXLAddins(TheXLApp As Excel.Application) As Boolean
Dim CurrAddin As Excel.AddIn
For Each CurrAddin In TheXLApp.AddIns
If CurrAddin.Installed Then
CurrAddin.Installed = False
CurrAddin.Installed = True
End If
Next CurrAddin
End Function
Using CreateObject("Excel.Application") would have the same result as using New Excel.Application, unfortunately.
You will have to load the Addins that you need individually by file path & name using the Application.Addins.Add(string fileName) method.
I'm leaving this answer here for anyone else who ran into this problem, but using JavaScript.
A little background... In my company we have a 3rd party web app that used JavaScript to launch Excel and generate a spreadsheet on the fly. We also have an Excel add-in that overrides the behavior of the Save button. The add-in gives you the option of saving the file locally or in our online document management system.
After we upgraded to Windows 7 and Office 2010, we noticed a problem with our spreadsheet-generating web app. When JavaScript generated a spreadsheet in Excel, suddenly the Save button no longer worked. You would click save and nothing happened.
Using the other answers here I was able to construct a solution in JavaScript. Essentially we would create the Excel Application object in memory, then reload a specific add-in to get our save button behavior back. Here's a simplified version of our fix:
function GenerateSpreadsheet()
{
var ExcelApp = getExcel();
if (ExcelApp == null){ return; }
reloadAddIn(ExcelApp);
ExcelApp.WorkBooks.Add;
ExcelApp.Visible = true;
sheet = ExcelApp.ActiveSheet;
var now = new Date();
ExcelApp.Cells(1,1).value = 'This is an auto-generated spreadsheet, created using Javascript and ActiveX in Internet Explorer';
ExcelApp.ActiveSheet.Columns("A:IV").EntireColumn.AutoFit;
ExcelApp.ActiveSheet.Rows("1:65536").EntireRow.AutoFit;
ExcelApp.ActiveSheet.Range("A1").Select;
ExcelApp = null;
}
function getExcel() {
try {
return new ActiveXObject("Excel.Application");
} catch(e) {
alert("Unable to open Excel. Please check your security settings.");
return null;
}
}
function reloadAddIn(ExcelApp) {
// Fixes problem with save button not working in Excel,
// by reloading the add-in responsible for the custom save button behavior
try {
ExcelApp.AddIns2.Item("AddInName").Installed = false;
ExcelApp.AddIns2.Item("AddInName").Installed = true;
} catch (e) { }
}

Resources