⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 webreplaydlg.cpp

📁 an automated software testing tool for Web applications
💻 CPP
📖 第 1 页 / 共 2 页
字号:
              {
                MSXML2::IXMLDOMNodePtr objXMLURL = objXMLAction->selectSingleNode(_T("@url"));
                _bstr_t bstrNavigateURL = objXMLURL->text;
                if (bstrNavigateURL != _bstr_t(_T("")))
                {
                  sprintf(strReplayMessage, "Replaying scenario step %d action %d navigate \"%s\" ...", intStep, intAction, (LPCTSTR)bstrNavigateURL);
                  m_objReplayStatus.SetWindowText(strReplayMessage);

                  m_objExplorer.Navigate(bstrNavigateURL, NULL, NULL, NULL, NULL);

                  // Go to Next Step
                  blnNextStep = true;
                }
              }
              else if (bstrActionType == _bstr_t(_T("control")))
              {
                MSXML2::IXMLDOMNodePtr objXMLName = objXMLAction->selectSingleNode(_T("@name"));
                _bstr_t bstrHTMLControlName = objXMLName->text;
                MSXML2::IXMLDOMNodePtr objXMLValue = objXMLAction->selectSingleNode(_T("@value"));
                _bstr_t bstrHTMLControlValue;
                if (objXMLValue)
                {
                  bstrHTMLControlValue = objXMLValue->text;
                }
                MSXML2::IXMLDOMNodePtr objXMLEvent = objXMLAction->selectSingleNode(_T("@event"));
                _bstr_t bstrHTMLControlEvent = objXMLEvent->text;
                if (bstrHTMLControlEvent == _bstr_t(_T("click")))
                {

                  sprintf(strReplayMessage, "Replaying scenario step %d action %d control name=\"%s\" value=\"%s\" click...", intStep, intAction, (LPCTSTR)bstrHTMLControlName, (LPCTSTR)bstrHTMLControlValue);
                  m_objReplayStatus.SetWindowText(strReplayMessage);

                  // Simulate a click on the requested button
                  if (SUCCEEDED(SimulateHTMLElementClick(bstrHTMLControlName, bstrHTMLControlValue)))
                  {
                    // Action succeeded: increase counter
                    this->m_objExplorer.m_nScenarioAction++;
                    // Go to Next Step
                    blnNextStep = true;
                  }
                  else
                  {
                    // Stop execution of following actions
                    blnNextStep = false;
                    break;
                  }
                }
                else if (bstrHTMLControlEvent == _bstr_t(_T("set_value")))
                {
                  sprintf(strReplayMessage, "Replaying scenario step %d action %d control name=\"%s\" value=\"%s\" set_value...", intStep, intAction, (LPCTSTR)bstrHTMLControlName, (LPCTSTR)bstrHTMLControlValue);
                  m_objReplayStatus.SetWindowText(strReplayMessage);

                  MSXML2::IXMLDOMNodePtr objXMLValue = objXMLAction->selectSingleNode(_T("@value"));
                  _bstr_t bstrHTMLControlValue = objXMLValue->text;
                  if (SUCCEEDED(SimulateTextInput(bstrHTMLControlName, bstrHTMLControlValue, bstrHTMLControlValue)))
                  {
                    // Action succeeded: increase counter
                    this->m_objExplorer.m_nScenarioAction++;
                    // Go to Next Step
                    blnNextStep = true;
                  }
                  else
                  {
                    // Stop execution of following actions
                    blnNextStep = false;
                    break;
                  }
                }
                else if (bstrHTMLControlEvent == _bstr_t(_T("wait")))
                {
                  sprintf(strReplayMessage, "Replaying scenario step %d action %d control name=\"%s\" value=\"%s\" wait...", intStep, intAction, (LPCTSTR)bstrHTMLControlName, (LPCTSTR)bstrHTMLControlValue);
                  m_objReplayStatus.SetWindowText(strReplayMessage);

                  if (bstrHTMLControlName == _bstr_t(_T("status")))
                  {
                    if (bstrHTMLControlValue == m_bstrStatusBarText)
                    {
                      // Action succeeded: increase counter
                      this->m_objExplorer.m_nScenarioAction++;

                      // Go to Next Step
                      blnNextStep = true;

                    }
                    else
                    {
                      // Set timer to wait for status bar text to appear
                      this->SetTimer(CWEB_HTML_ELEMENT_TIMER, m_intTimeoutMilliseconds, NULL);

                      // Do not proceed with next step - we must wait until the control has the requested value
                      blnNextStep = false;

                      // Stop execution of following actions
                      break;
                    }
                  }
                  else
                  {
                    MessageBox(_T("ERROR: Unknown wait control name: must be 'status'"));
                    break;
                  }
                }
                else
                {
                  MessageBox(_T("ERROR: Unknown control event: must be 'click', 'wait' or 'set_value'"));
                  break;
                }
              }
              else
              {
                MessageBox(_T("ERROR: Unknown action type: must be 'navigate' or 'control'"));
                break;
              }

            } // if (this->m_objExplorer.m_nScenarioAction >= intAction)

          } // for (long intAction = 0; intAction < objXMLActions->length; intAction++)

          if (blnNextStep)
          {
            this->m_objExplorer.m_nScenarioStep++;
            this->m_objExplorer.m_nScenarioAction = 0;
            break;
          }

        } // if (objXMLActions->length > 0)

      } // if (this->m_objExplorer.m_nScenarioStep >= intStep)

    } // for (long intStep = 0; intStep < objXMLSteps->length; intStep++)

    if (this->m_objExplorer.m_nScenarioStep == objXMLSteps->length)
    {
      // End of loop - reset state
      this->m_objExplorer.m_nScenarioLoops++;

      if (blnInfiniteLoops)
      {
        if (TRUE) // TODO test if last action is not navigate or click
        {
          EndScenario();
        }

        // Start replaying all over again
        this->m_objExplorer.m_nScenarioStep = 0;
        this->m_objExplorer.m_nScenarioAction = 0;

        // Post message to simulate a click on Replay button
        CWnd * pReplayButton = GetDlgItem(IDC_BUTTON_REPLAY);
        if (pReplayButton)
        {
          ::PostMessage(pReplayButton->m_hWnd, BM_CLICK, (WPARAM)0, (LPARAM)0);
        }
      }
      else
      {
        // Stop replaying
        this->m_objExplorer.m_nScenarioStep = -1;
        this->m_objExplorer.m_nScenarioAction = 0;

        if (TRUE) // TODO test if last action is not navigate or click
        {
          EndScenario();
        }

      }

    } // if (this->m_objExplorer.m_nScenarioStep == objXMLSteps->length)

  } // if ((bool)varOut == FALSE)
}


void CWebReplayDlg::EndScenario()
{
  m_objReplayStatus.SetWindowText("Scenario completed.");
  // Put back focus on scenario file name (so that you can REPLAY again by pressing the ENTER key)
  CWnd * pFocus = m_objScenarioFileName.SetFocus();
  m_objScenarioFileName.SetSel(0, -1);
  // Enable "Replay" button
  m_objReplayButton.EnableWindow(TRUE);
  m_objScenarioFileName.EnableWindow(TRUE);
}


//
// ***************************************************************************
//
// UTML Element and Event Handling Functions
//
// ***************************************************************************
//

CComQIPtr<IHTMLElement, &IID_IHTMLElement> CWebReplayDlg::GetHTMLElement(const OLECHAR *BSTRElementName, const OLECHAR *BSTRElementValue)
{
  CComQIPtr<IHTMLElement, &IID_IHTMLElement>      pHTMLElement;

  VARIANT                                         name, index;
  _bstr_t strRequestedValue = _bstr_t(BSTRElementValue);
  
  VariantInit(&name);
  V_VT(&name) = VT_BSTR;
  V_BSTR(&name) = SysAllocString(BSTRElementName);
  VariantInit(&index);
  V_VT(&index) = VT_I2;
  V_I2(&index) = 0;

  CComPtr<IHTMLElementCollection>                 pEltColl = NULL;
  CComPtr<IDispatch>                              pEltDisp = NULL;
  CComQIPtr<IHTMLDocument2, &IID_IHTMLDocument2>  pDoc2;
  CComPtr<IDispatch>                              pDisp = NULL;

  CHECKPTR(pDisp = m_objExplorer.get_Document());    
  CHECKPTR(pDoc2 = pDisp);

  //Get the element you want to fire the event on.
  HRESULT hResult = pDoc2->get_all(&pEltColl);
  if (SUCCEEDED(hResult) && pEltColl)
  {
    // We are assuming there's only one element with that name on the page,
    // else you must expect a collection instead of a single element.
    if (name == L"" && BSTRElementValue != L"")
    {
      // Search by value (manual search with a loop on all HTML Elements in document - could be long!)
      long intElements = 0;
      pEltColl->get_length(&intElements);
      for (int intElement = 0; intElement < intElements; intElement++)
      {
        CComPtr<IDispatch> pCurrentDispatch = NULL;
        
        VARIANT vElementIndex;
        VariantInit(&vElementIndex);
        V_VT(&vElementIndex) = VT_I4;
        V_I4(&vElementIndex) = intElement;
        hResult = pEltColl->item(vElementIndex, index, &pCurrentDispatch);
        if (SUCCEEDED(hResult))
        {
          // Read value from current element
          CComQIPtr<IHTMLInputElement, &IID_IHTMLInputElement> pCurrentInputElement = pCurrentDispatch;
          if (pCurrentInputElement)
          {
            BSTR bstrValue = NULL;
            pCurrentInputElement->get_value(&bstrValue);
            _bstr_t strValue = bstrValue;
            if (strValue == strRequestedValue)
            {
              // Found input element with requested value - return this
              pHTMLElement = pCurrentDispatch;
              // Cleanup
              if (bstrValue)
              {
                SysFreeString(bstrValue);
              }
              break;
            }

            // Cleanup
            if (bstrValue)
            {
              SysFreeString(bstrValue);
            }
          }
          else
          {
            // Try with an hyperlink (search in its HREF and innerText attributes)
            CComQIPtr<IHTMLAnchorElement, &IID_IHTMLAnchorElement> pCurrentAnchorElement = pCurrentDispatch;
            if (pCurrentAnchorElement)
            {
              CComQIPtr<IHTMLElement, &IID_IHTMLElement> pCurrentHTMLElement = pCurrentDispatch;
              
              BSTR bstrHref = NULL;
              pCurrentAnchorElement->get_href(&bstrHref);
              _bstr_t strHref = bstrHref;

              BSTR bstrInnerText = NULL;
              pCurrentHTMLElement->get_innerText(&bstrInnerText);
              _bstr_t strInnerText = bstrInnerText;
              if (strInnerText == strRequestedValue || strHref == strRequestedValue)
              {
                // Found input element with requested value - return this
                pHTMLElement = pCurrentDispatch;
                // Cleanup
                if (bstrInnerText)
                {
                  SysFreeString(bstrInnerText);
                }
                break;
              }

              // Cleanup
              if (bstrInnerText)
              {
                SysFreeString(bstrInnerText);
              }
            }
          } // if (pCurrentHTMLElement)
        }
      }
    }
    else
    {
      hResult = pEltColl->item(name, index, &pEltDisp);
      if (FAILED(hResult) || !pEltDisp)
      {
        /*
        _TCHAR strErrorMessage[4096];
        sprintf(strErrorMessage, _T("ERROR: Can't find HTML Element named \"%S\"!"), BSTRElementName);
        MessageBox(strErrorMessage);
        */
      }
      else
      {
        pHTMLElement = pEltDisp;
      }
    }
  }

  if (!pHTMLElement)
  {
    // Add delay before issuing error and giving up - some HTML Element are generated dynamically 
    // long after the document has been loaded!
    this->SetTimer(CWEB_HTML_ELEMENT_TIMER, m_intTimeoutMilliseconds, NULL);
  }

cleanup:
    if (V_BSTR(&name))
        SysFreeString(V_BSTR(&name));

  return(pHTMLElement);
}

HRESULT CWebReplayDlg::SimulateHTMLElementClick(const OLECHAR *BSTRElementName, const OLECHAR *BSTRElementValue)
{
  HRESULT hResult = E_FAIL;
  CComQIPtr<IHTMLElement, &IID_IHTMLElement>      pHTMLElement = GetHTMLElement(BSTRElementName, BSTRElementValue);

  if (pHTMLElement)
  {
    // Directly click on element
    hResult = pHTMLElement->click();
  }

  return(hResult);
}

HRESULT CWebReplayDlg::SimulateTextInput(const OLECHAR *BSTRHtmlControlName, const OLECHAR *BSTRHtmlControlValue, const OLECHAR *BSTRText)
{
  HRESULT hResult = E_FAIL;
  CComQIPtr<IHTMLElement, &IID_IHTMLElement>      pHTMLElement = GetHTMLElement(BSTRHtmlControlName, BSTRHtmlControlValue);

  // Try with an HMTL Input element
  CComQIPtr<IHTMLInputElement, &IID_IHTMLInputElement> pInputElement = pHTMLElement;
  if (pInputElement)
  {
    // Directly change the "value" attribute of HTML Element
    hResult = pInputElement->put_value(OLE2BSTR(BSTRText));

    // Fire the "onblur" event - some javascript handler may require this after a value changes...
    SimulateFireEvent(pHTMLElement, L"onblur");

  }
  else
  {
    // Try with an HTML SELECT element
    CComQIPtr<IHTMLSelectElement, &IID_IHTMLSelectElement> pSelectElement = pHTMLElement;
    if (pSelectElement)
    {
      // Directly change the "value" attribute of HTML Element
      hResult = pSelectElement->put_value(OLE2BSTR(BSTRText));

      // Fire the "onblur" event - some javascript handler may require this after a value changes...
      SimulateFireEvent(pHTMLElement, L"onblur");
    }
  }

  return(hResult);
}

HRESULT CWebReplayDlg::SimulateFireEvent(CComQIPtr<IHTMLElement, &IID_IHTMLElement> pHTMLElement, const OLECHAR *BSTREventName)
{
  HRESULT hResult = E_FAIL;
  BSTR                                           eventName = NULL;
  VARIANT                                        eventobj;
  VARIANT_BOOL                                   vBool;    
  CComPtr<IDispatch>                             pDisp = NULL;
  CComQIPtr<IHTMLDocument4, &IID_IHTMLDocument4> pDoc4;
  CComPtr<IHTMLEventObj>                         pEvent = NULL;
  CComQIPtr<IDispatch, &IID_IDispatch>           pEventDisp;
  CComQIPtr<IHTMLElement3, &IID_IHTMLElement3>   pElt3;

  CHECKPTR(pDisp = m_objExplorer.get_Document());    
  CHECKPTR(pDoc4 = pDisp);

  hResult = pDoc4->createEventObject(NULL, &pEvent);
  if (FAILED(hResult) || !pEvent)
  {
    goto cleanup;
  }

  CHECKPTR(pEventDisp = pEvent);

  // Set event name
  eventName = SysAllocString(BSTREventName);
  VariantInit(&eventobj);
  V_VT(&eventobj) = VT_DISPATCH;
  V_DISPATCH(&eventobj) = pEventDisp;

  // Fire the event.
  CHECKPTR(pElt3 = pHTMLElement);
  hResult = pElt3->fireEvent(eventName, &eventobj, &vBool);

cleanup:
  if (eventName)
      SysFreeString(eventName);

  return(hResult);
}

void CWebReplayDlg::OnBnClickedButtonReplay()
{
  m_objReplayButton.EnableWindow(FALSE);
  m_objScenarioFileName.EnableWindow(FALSE);

  // Save scenaro file name 
  CString strXMLFileName;
  m_objScenarioFileName.GetWindowText(strXMLFileName);
  WritePrivateProfileString("WebReplay", "ScenarioFileName", strXMLFileName, m_strConfigFile);

  ResetScenario();
  ReplayScenario();
}

void CWebReplayDlg::OnBnClickedCancel()
{
  OnCancel();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -