/// <summary> /// parses the complete MHT source and returns the corresponding Source Workitem /// </summary> /// <returns></returns> public ISourceWorkItem GetNextWorkItem() { if (m_isProcessed) { return(null); } else { m_isProcessed = true; } // The Source WorkItem which has to return ISourceWorkItem workItem = new SourceWorkItem(); // The Complete range of the MHT file Range documentRange = m_document.Range(Type.Missing, Type.Missing); MHTSection mhtSection = MHTSection.Skip; string fieldName = string.Empty; bool skipMHTSectionCheck = false; if (m_storageInfo.IsFirstLineTitle) { m_storageInfo.TitleField = TestTitleDefaultTag; skipMHTSectionCheck = true; mhtSection = MHTSection.Title; } // Initializing paragraphNumber int paragraphNumber = 1; // String Builder to store the text parsed from mht StringBuilder textBuilder = new StringBuilder(); var testSteps = new List <SourceTestStep>(); // bool to check that whether line to parse is first line in the section or not bool isFirstLineInSection = true; // Loop to traverse the complete MHT Source while (paragraphNumber <= documentRange.Paragraphs.Count) { // The Current pargraph to parse Paragraph paragraph = documentRange.Paragraphs[paragraphNumber]; string paragraphText = CleanString(paragraph.Range.Text); // If this paragraph is empty line then continue to next paragraph if (string.IsNullOrEmpty(CleanString(paragraph.Range.Text))) { paragraphNumber++; } // else parse the paragraph else { bool isFieldName = false; foreach (SourceField field in StorageInfo.FieldNames) { if (String.CompareOrdinal(field.FieldName, paragraphText) == 0) { isFieldName = true; break; } } if (!skipMHTSectionCheck && isFieldName) { MHTSection previousMHTSection = mhtSection; if (String.CompareOrdinal(paragraphText, m_storageInfo.TitleField) == 0) { mhtSection = MHTSection.Title; } else if (String.CompareOrdinal(paragraphText, m_storageInfo.StepsField) == 0) { mhtSection = MHTSection.Steps; } else if (m_fieldNameToFields.ContainsKey(paragraphText)) { if (m_fieldNameToFields[paragraphText].IsHtmlField) { mhtSection = MHTSection.History; } else { mhtSection = MHTSection.Default; } } else { mhtSection = MHTSection.Skip; } isFirstLineInSection = true; UpdateSourceWorkItem(previousMHTSection, workItem, fieldName, textBuilder, testSteps); fieldName = paragraphText; } switch (mhtSection) { case MHTSection.Title: // If the current paragraph has test Title Label then skip if (String.CompareOrdinal(paragraphText, m_storageInfo.TitleField) == 0) { paragraphNumber++; } // else if we have not reached the end of Test Title Section else { textBuilder.Append(CleanString(paragraph.Range.Text)); if (isFirstLineInSection) { isFirstLineInSection = false; } paragraphNumber++; } skipMHTSectionCheck = false; break; case MHTSection.History: if (isFirstLineInSection) { textBuilder.Append("<div>"); isFirstLineInSection = false; } if (paragraph.Range.Tables.Count > 0) { textBuilder.Append(GetHTMLTable(paragraph.Range.Tables[1])); paragraphNumber = GetParagraphNumberAfterSpecifiedRange(documentRange, paragraph.Range.Tables[1].Range.End); } else if (paragraph.Range.InlineShapes.Count > 0) { string fileName = "Image" + (++m_workItemAttachmentCount) + ".bmp"; string filePath = Path.Combine(Path.GetTempPath(), fileName); ExtractImage(paragraph.Range.InlineShapes[1].Range, filePath); textBuilder.Append("<div><img src='" + filePath + "' /></div>"); paragraphNumber++; } else if (String.CompareOrdinal((paragraph.get_Style() as Style).NameLocal, "Heading 2") == 0) { textBuilder.Append("<h2>" + CleanString(paragraph.Range.Text).Replace("<", "<").Replace(">", ">") + "</h2>"); paragraphNumber++; } else { textBuilder.Append("<div>" + SecurityElement.Escape(CleanString(paragraph.Range.Text)) + "</div>"); paragraphNumber++; } break; case MHTSection.Steps: if (paragraph.Range.Tables.Count == 0) { paragraphNumber++; } else { Tables stepsTables = paragraph.Range.Tables; foreach (Table table in stepsTables) { int rowNumber = 0; foreach (Row currentRow in table.Rows) { if (!currentRow.IsFirst) { rowNumber++; string title = string.Empty; string expectedResult = string.Empty; List <string> attachments = new List <string>(); int attachmentCount = 0; string attachmentPrefix = "Step" + rowNumber; if (currentRow.Cells.Count == 1) { title = ParseTestStepCell(currentRow.Cells[1], attachments, attachmentPrefix, ref attachmentCount, 1); } else if (currentRow.Cells.Count == 3) { title = ParseTestStepCell(currentRow.Cells[2], attachments, attachmentPrefix, ref attachmentCount, 1); expectedResult = ParseTestStepCell(currentRow.Cells[3], attachments, attachmentPrefix, ref attachmentCount, 1); } else { throw new WorkItemMigratorException("Steps table is not in correct format", "Steps table is not having three columns.", "Please make sure that you have mapped the correct field to 'Steps'."); } if (!string.IsNullOrEmpty(title) || !string.IsNullOrEmpty(expectedResult)) { testSteps.Add(new SourceTestStep(title, expectedResult, attachments)); } } } } paragraphNumber = GetParagraphNumberAfterSpecifiedRange(documentRange, paragraph.Range.Tables[1].Range.End); } break; case MHTSection.Default: if (isFirstLineInSection) { isFirstLineInSection = false; } else { textBuilder.Append(CleanString(paragraph.Range.Text)); } paragraphNumber++; break; case MHTSection.Skip: paragraphNumber++; break; default: break; } } } UpdateSourceWorkItem(mhtSection, workItem, fieldName, textBuilder, testSteps); if (m_storageInfo.IsFileNameTitle) { string title = Path.GetFileNameWithoutExtension(StorageInfo.Source); workItem.FieldValuePairs.Add(MHTParser.TestTitleDefaultTag, title); } workItem.SourcePath = StorageInfo.Source; RawSourceWorkItems.Add(workItem); ParsedSourceWorkItems.Add(workItem); return(workItem); }
/// <summary> /// Parses and returns the next workitem present in the Excel Source /// </summary> /// <returns></returns> public ISourceWorkItem GetNextWorkItem() { if (m_currentRow > m_lastRow) { return(null); } int workItemStartingRow = -1; string error = null; // It represents the state that it has started the parsing of the excel workitem or not bool isReadingNextWorkItemStarted = false; // The Internal Representation of TFS workItem. ISourceWorkItem xlWorkItem = new SourceWorkItem(); // The List of Test Steps List <SourceTestStep> steps = new List <SourceTestStep>(); // While The end of work item is not encountered parse the current row and update the Excel Work Item while (!IsWorkItemCompleted(isReadingNextWorkItemStarted)) { if (workItemStartingRow == -1) { workItemStartingRow = m_currentRow; } m_storageInfo.ProgressPercentage = (m_currentRow * 100) / m_lastRow; // Parsing of work item is now started. So switch on the bool variable isReadingNextWorkItemStarted = true; string testStepTitle = string.Empty; string testStepExpectedResult = string.Empty; // Itrerating throgh each fields and reading value present in corresponding cells and then updating // m_dataStore.DataValuesByFieldName and Excel WorkItem foreach (KeyValuePair <string, int> kvp in m_selectedHeadersToColumn) { // Get Value at(currentrow,columnForCurrentHeaderInProcess) string value = GetValueAt(m_currentRow, kvp.Value); if (!string.IsNullOrEmpty(value)) { // If the Current field is mapped to TFS Test Step Title field then update the step's title if (FieldNameToFields[kvp.Key] is TestStepTitleField) { testStepTitle = value; } // else if the Current field is mapped to TFS Test Step Expected result field then update the step's expected result else if (FieldNameToFields[kvp.Key] is TestStepExpectedResultField) { testStepExpectedResult = value; } // else if it is mapped to a date time field then parse it else if (FieldNameToFields[kvp.Key].Type == typeof(DateTime)) { double excelDate; if (double.TryParse(value, out excelDate)) { DateTime dateOfReference = new DateTime(1900, 1, 1); excelDate = excelDate - 2; try { xlWorkItem.FieldValuePairs[kvp.Key] = dateOfReference.AddDays(excelDate); } catch (ArgumentException) { // If argument provided is wrong then don't set anyting xlWorkItem.FieldValuePairs[kvp.Key] = null; } } else { xlWorkItem.FieldValuePairs[kvp.Key] = null; } } // else just update the exel workitem else { if (!xlWorkItem.FieldValuePairs.ContainsKey(kvp.Key)) { xlWorkItem.FieldValuePairs.Add(kvp.Key, value); } else { xlWorkItem.FieldValuePairs[kvp.Key] += "\n" + value; } } } // else if this field is not already filled and it is not test step(title or expected result) field then set it to null. else if (!xlWorkItem.FieldValuePairs.ContainsKey(kvp.Key) && !(FieldNameToFields[kvp.Key] is TestStepTitleField) && !(FieldNameToFields[kvp.Key] is TestStepExpectedResultField)) { xlWorkItem.FieldValuePairs.Add(kvp.Key, null); } } // If we found step in the current row then update the list of excel steps if (!string.IsNullOrEmpty(testStepTitle) || !string.IsNullOrEmpty(testStepExpectedResult)) { SourceTestStep step = new SourceTestStep(); step.title = testStepTitle.Trim(); step.expectedResult = testStepExpectedResult.Trim(); steps.Add(step); } // Done with parsing of current row. Move to next row m_currentRow++; } if (!string.IsNullOrEmpty(StorageInfo.SourceIdFieldName)) { string value = GetValueAt(workItemStartingRow, m_headersToColumn[StorageInfo.SourceIdFieldName]); if (string.IsNullOrEmpty(value)) { error += "Source Id Is Not found\n"; } else { xlWorkItem.SourceId = value; } } if (!string.IsNullOrEmpty(StorageInfo.TestSuiteFieldName)) { string value = GetValueAt(workItemStartingRow, m_headersToColumn[StorageInfo.TestSuiteFieldName]); if (!string.IsNullOrEmpty(value)) { foreach (string testSuite in value.Split(';', '\n')) { string s = testSuite.Trim(); if (!string.IsNullOrEmpty(s)) { xlWorkItem.TestSuites.Add(s); } } } } foreach (ILinkRule linkInfo in StorageInfo.LinkRules) { string value = GetValueAt(workItemStartingRow, m_headersToColumn[linkInfo.SourceFieldNameOfEndWorkItemCategory]); if (!string.IsNullOrEmpty(value)) { foreach (string linkedWorkItemId in value.Split(';')) { string trimmedId = linkedWorkItemId.Trim(); if (!string.IsNullOrEmpty(trimmedId)) { Link link = new Link(); link.StartWorkItemCategory = linkInfo.StartWorkItemCategory; link.StartWorkItemSourceId = xlWorkItem.SourceId; link.LinkTypeName = linkInfo.LinkTypeReferenceName; link.EndWorkItemCategory = linkInfo.EndWorkItemCategory; link.EndWorkItemSourceId = trimmedId; xlWorkItem.Links.Add(link); } } } } if (steps != null && steps.Count > 0) { // Done with parsing of XL Work Item. Add the List of steps in the XL Work Item. xlWorkItem.FieldValuePairs.Add(TestStepsFieldKeyName, steps); } xlWorkItem.SourcePath = StorageInfo.Source; if (!string.IsNullOrEmpty(error)) { xlWorkItem = new FailedSourceWorkItem(xlWorkItem, error); } RawSourceWorkItems.Add(xlWorkItem); xlWorkItem = ApplySettings(xlWorkItem); ParsedSourceWorkItems.Add(xlWorkItem); // return the Excel WorkItem return(xlWorkItem); }