2016-11-07 279 views
0

我有一個控制,我想知道它的動畫開始和結束。我最終編寫了類似於下面的代碼的東西,但是在我的測試中(Mocha + Phantom + Karma),onAnimationEnd事件似乎並沒有觸發。ReactJS onAnimationEnd在測試期間不執行

開始很容易,因爲它發生在點擊上,但最終是我目前的問題。我在下面添加了一個例子。如果有人能看到我想知道的問題是什麼!

P.S. - 抱歉沒有代碼片段,我不知道任何處理測試用例的片段生成器。

CSS

@keyframes exampleAnimation { 
    0% { 
     opacity: 1; 
    } 
    100% { 
     opacity: 0; 
    } 
} 

.testObject { 
    &.animate { 
     animation-name: exampleAnimation; 
     animation-duration: 1s; 
     animation-timing-function: ease-out; 
    } 
} 

打字稿

import React = require("react"); 

export interface ITestControlProps { 
    /** 
    * Called when the element is clicked 
    */ 
    onClick?:() => void; 

    /** 
    * Called when the animation is complete 
    */ 
    onAnimationComplete?:() => void; 
} 
export interface ITestControlState { 
    /** 
    * if the element has been clicked 
    */ 
    isClicked: boolean; 
} 

export class TestControl extends React.Component<ITestControlProps, ITestControlState> { 

    constructor() { 
    super(); 
    this.state = { 
     isClicked: false 
    }; 
    } 

    public render(): JSX.Element { 
     let buttonClassName = "testObject "; 

     if (this.state.isClicked) { 
      buttonClassName += " animate"; 
     } 

     return (
      <button 
       className = {buttonClassName} 
       onClick = {this.onClick.bind(this)} 
       onAnimationEnd = {this.onAnimationComplete.bind(this)} 
       > 
       Click me! 
      </button> 
     ); 
    } 

    /** 
    * When the button is clicked 
    * @param evt: The event that caused this method to be called. Can be a click or a button press. 
    */ 
    private onClick(evt: UIEvent) { 
     this.setState((prevState: ITestControlState) => { 
      prevState.isClicked = !prevState.isClicked; 
      return prevState; 
     }); 

     if (this.props.onClick != null) { 
      this.props.onClick(); 
     } 

     console.log("On click fired"); 
    } 

    /** 
    * When the pulse animation is complete 
    */ 
    private onAnimationComplete(): void { 
     if (this.props.onAnimationComplete != null) { 
      this.props.onAnimationComplete(); 
     } 
     console.log("onAnimationComplete fired"); 
    } 
} 

打字稿 - 測試

import chai = require("chai"); 
import React = require("react"); 

// Control 
import {TestControl} from "planner/controls/PresentationalControls"; 

const expect = chai.expect; 
const TestUtils = React["addons"].TestUtils; 

describe("TestControl Control Unit Test",() => { 

    let renderedComponent: TestControl; 

    describe("TestControl default render",() => { 

     it ("Animation Complete Success", (done: MochaDone) => { 
      let animationCompleteFunc =() => { 
       done(); 
      }; 

      renderedComponent = TestUtils.renderIntoDocument(
       <TestControl 
        onAnimationComplete = {animationCompleteFunc}> 
       </TestControl> 
      ); 

      expect(renderedComponent).to.not.be.undefined; 

      var button = TestUtils.scryRenderedDOMComponentsWithTag(renderedComponent, "button")[0]; 

      TestUtils.Simulate.click(button); 
     }); 
    }); 
}); 
+0

請注意,我認爲這可能與虛擬dom(誰知道這一點)有關,所以我還使用ReactDom將其呈現在文檔的正文中,但我仍然沒有得到該事件。 – k2snowman69

回答

0

這需要兩個變化。首先在控制文件的頂部,您需要添加

///<amd-dependency path="./PulseButton.css" /> 

第二個TestUtils實際上並不會從DOM中觸發事件。這意味着儘管您的代碼可以在瀏覽器中運行,但您不能使用TestUtils來編寫這些測試。

相反,您必須實際以幻影的方式將組件安裝到文檔以使事件正確觸發。