tJ>p=p4Vg>VK#aJd9kFOhh2D!93Fu_u@Sd^3TZpO1@OiNc$B^<@EsF#@63#GYNv@S3!&=>HFqGIg~wthu+3sj0&rRwSX
zO?MS94>FI&Gth&D6_>TYHLdmL7e@HlDY4>k466-Veov!wCz4?dO@}ImP?wg6mheN?
zTOO2S%>K7p_Z#^eae(((p!X%oa3p3yk1r4DsH*_9azJl&Ld=&2&up1d
zS3tKAD)yb_=Ipa>fdUV4()cR=+8;|QD^Uv7QkLR2^c
z#sk>*X2a44ZRrD9G&al}4t^XFWFo8M$n0k?SKNBuOyUPF@Wxe2ycNm0zl5j1rY)JD
zNcy@_^g$f5Wr99<)M)FlAtd(32m$hR5Qo{?Kd1|6vnl3BnzouC5y=QttZG9KzIkz1
zwpv7-IVtshb^UaVY=96W@OX^WJ$7l7lbiF^f1oBfphJ+r7+`L~-)8SQqn+^-w3x!h?EPV4Vx%a!I!5
zOIK>>Go24q-nU&8x{|>JJfe}h<(Fz?Not)jwL)h#wkv50fH;LAlpIsPDi_7Epv#-H
z?+GK)`w*PsTkO0~{hEh1-Q~8mCNw1C0|s!Y*p0@6JsMk@B?6zgMYzbF#z6dpD%WmK
z?VL6fX}91j72GV8J2*1tkX;h*OGEvHY>ATQM+9(88m@m;7EM?xgmL@yyo7d1?VLRzby1N^8)(`K3PwnzdYq
zQ4TH?lwk;Md`3(fn}ia~r^Ir`t)-cTFhu5AG}eM{J8V-9+__K78-gB8Z7cNz$$^i$
zh@5@T?1T5EW(SDqn_RUrMt(ox1g`5J){?ZSdvmU7H)S745dh&I4ZUfZ?iUS
zKov*C%A>frC)KK;jLml!DnnBluE+t?hKO6wysdSQ`$W90(Hi)|MfMOUd+(acSY*xK
ztT-HL{3#-U1vo@@`r45{(k810xUMWqDz+OJNqgEeE|
za41p7Va;95QbQ5=lW43*A~$KYjE1yV`y50B>`*X@*k}zm!8$Rk;OP^o
zLBsEt&zl^RU?P$*gi1|Vp52`qvK8*M_Mk5Jz@FdGb>=fsxNziR)MZxHb!zM6p%8sP
z*K_>at7{8p48$=EVc-er`=>{gANk58ch~f5Epd1Xz>)DNzN9c}PJ7ITG!#^Q8*TAQ
zh5+~t&+xEJYq!+$ULN=M7*=zqQ~}#
zF4hbNkwM2j2#wL7DCG?A*|Ltity5$GAA4GgG8TzfL1R~l8^6``CS173Q)Nc?o>f0S
z8gvsF#3NbM-1H|x56smcYE_7Yo~JXT%*zy!EQsQ|u5fLt6@OmxXhF%LbFH=WS=TlM
zy%-RAx`ugY;W&kfAtUDX=9jJ1d-2V}#Nkc!VU_cecHR}p}aJN8}yp^vLgYsL+s1Vu>svEM{
z1k$s5%T{5vZb#qBcRJOLV{BjIs5pDEI2y}Nuxa!7tY=U-(bB}dh&d+5M0CUu`0x2$
z)cP&E?MhrZ%dOKSQ2V}xpZo*bm@Z5VDXxwe$`k#aIz9yR!&Ib@MnqITM6xh^jE?X*
zLDE;QOPp;v;IJHSeSxB!t*~V
zFk?}-C0`dOLKp$P3YS(UD;X1_yLnIbdWcCGZeLbQOL`j1vZ%8q}BADNQ%aoj6zbni#O+ehz
zi!yrb5qY|>tYxLtj&X|MrWgsdvcZW{LncS`$Mt!6Q%oiabFexElh~1?>@dt=NwC^n
zkL;#*6kra>$D3j`Y5U$sIe6xMK=n%|$_=
z4P1Lgk7Q=QQR78Uxnxu-j0lYE7JYfZYrF#qbNgFujSOg5WV!9KRPJ>8fnZ61HUELP
zN25Yk-}_(Tq&ycV6Wo`_9-U$Rp!~I;J1IOV5XtH&u1egPh(LQYJ+{$&
zum$6_YYrI`A?d}c>;}-=+Bm?#XGqZ`TW!u)cys1Pg{puNr_q*gTh?x(1crbWUpVC+
zJ??JPLGEo3CVA`d*OfTE#1@O7vEEm|cG>asIeJY@^hU=i`v)X%%$@Vxhd5@4U@Ur8
zqd9$-Td5KjxNp*G{l4TqAl)1w&t1B2|2Ja{T?#Ku@j<@kM(E{b4$1XD&%j383o+|_
z=hfNC%iz^7{xl|=
zNF%2zcuq&xAY^!*=6T1A3Cyxc_nB0+$(65&yyoNS4EoD&k%C_zNs!qJ&L2+
zNGS;yHlr6@!#RJcPUqk$1Y`N(g`=g4_&Qve^XZ`bjzc|~?&BGWx2n>REC#3EzLAnq
zN!g!l|M1;LZf()Ho(=aFe3Sy9KQu5)+y8g@i~n4!wD2|Uy&Y!X-LG9sZG@Kbv2`IM
z(;tn+U!9j0jv1ed)t$AH4O>!J`b(8PZjL7wytJ2N4k(+kd!>V5baA})(UYJkmlvhL
zruf>+-|=9SR{m5?gI15^&{674Z~0B8C3MkCq}Gp+e*^rHyhj=
zGq!I0a4$*uSzX+)c-b=uL&(%vifxGu9Pa$a5%KU5Nn`0-cNe`iIF%&mZgh9QmYj9L
z%l9t5GOTsmXQU?FtvZurTu^$IqI9BH=x2Y+TJNyk+a>t9D@1U9fviC0dR*1l7q
zmD9Ug+e$oy_%I
zK74cWEYC7RMz(%=aqBBiQ@fO
zWtgMzemH9K*O!l+q7T~p(vL5!V#@mmYE~?**{6o`|phvcWo!%J&fG8KF9y^+&;5G*Q)c|
z0e>Fvv}^y?FkQQ-i(p(XUuBRR!#!bXBl@-4w7VxXIZf8IC2h!`)8BY)8d8%~re7a$
zr*+ZpTdjC&D3ax&=59=i`{dk@nTtZ@htpV5T)0SKoLrsM$Vk^>*t>
zLf_zS3fG9Gy9#C;9}MD=V}#_yAjG)9NKe-ZsXywoBRDc)R7U#ds3E7YTs3r9EU-Md
zP>V?6Lvdm6o%$u4Uk~e#!#q(*96$Fwn9H*o*(2(;l|!3#6vPn7?G1ZfmfDJ3wpYD_
z7vUYo?;gAWGj&+B^Eyp}nK=2`U5#YX?Q8YR#Vzc8|J*fO9ecR&ODYVs
zH|?^8&{&G7r66yLA&exoey=b%{Ao9;UOeV<8o^kJNDM#a693=LP`PgfKf)-d)BO0K
z@xwYQ(x7#H`4?_1^v$A5tB{9q$vfCXP8C}yJ*;{N5`XxDUb=);=5W|JR9Wn>)_kzv
zD3AaPH`R+WdC+YpXOX7ft!F(*?nz(aRNh^69lAbx*(32*K2+>C%|KV!zk%UOK=nEN
zAFVSdiyqv*4CA)+oqlD&9_uWCTzNh!`M1|GOWFGwPlNEI*7Q0ym}l=;nW#^W5RJ~{8nhI44%-8@WwuA27$x60%B7WcUx{Z@cdb7tMsb<
zUTapl8;vC}O+Jc-!Hz_j>D8f{5KopAG*qtqxI|cFg;_y`|lCo`~=&7J~&98czo-eSU&|&Dlm(y$to;Dh$8%3
z4`$4(yN;FS0;IXb!n1o?`OVNpRD{V<>4BYs(MW$+ozp6Y0M3tbw7u-tgSk1fO!{At{*6
z(!SnVgC>{!rqW4uYctXT*45{kwoTqXZYc5j_t0_>*F)D{jxH*K1W5;RNK;
z%6@O!!L01y-hGgPpA9n&q~*#W>%SdZSyn^v`xCD>zskMG1LAICFD=(s+C|CC#>IDhm0b(;joA#oW(wPk+Mn4R4Fcn?)hKNJ4Cm9II?BUY
zaagZ^#tnwcn8ZV<^XN4Um-LJ-95}<^fWGu$YQ~fJ{Lzlg^3sy{bkVek-N(H@qY^z%Z?XtzD
zuwhiUOLjy6dKXcLVeM98*%Adpwi~DS7{a}{y`mexlm^h;}bgC$IH0D&u!y$
zQ+*Z-g_fe9Sp7p}fvOVhwPT&D9do-YO4B+++u
zZ_n5a_PDw8Z}f;mozNrrvCsciAIMp-e%WToW8PnT {}, 2000);
- });
-
- after(function() {
- document.body.innerHTML = originalBodyHTML;
- });
-
- describe('1. Initialization and Setup', function() {
- afterEach(function() {
- setTimeout(() => {}, 2000);
- });
-
- it('a. Should initialize correctly on a given DOM element', function() {
- expect($button).to.exist;
- });
-
- it('b. Should create the button with correct text', function() {
- expect($button.text()).to.equal('Capture Screen');
- });
-
- it('c. Should make the button visible on the page', function() {
- expect($button.is(':visible')).to.be.true;
- });
- });
-
- describe('2. Button Functionality', function() {
- afterEach(function() {
- setTimeout(() => {}, 2000);
- });
-
- it('a. Should trigger screenshot process on click', function() {
- sinon.stub(window, 'html2canvas').resolves(document.createElement('canvas'));
- return waitForClick($button)
- .then(() => {
- expect(html2canvas.called).to.be.true;
- expect(html2canvas.callCount).to.equal(1);
- html2canvas.restore();
- });
- });
-
- it('b. Should hide button during screenshot process', function(done) {
- sinon.stub(window, 'html2canvas').resolves(document.createElement('canvas'));
- $button.click();
- expect($button.hasClass(flagIsHidden)).to.be.true;
- html2canvas.restore();
- done();
- }
- );
-
- it('c. Should show button after screenshot is taken', function() {
- sinon.stub(window, 'html2canvas').resolves(document.createElement('canvas'));
- return waitForClick($button)
- .then(() => {
- expect($button.hasClass(flagIsHidden)).to.be.false;
- html2canvas.restore();
- });
- });
- });
-
- describe('3. Input Handling', function() {
- let $input, $textarea;
-
- beforeEach(function() {
- $input = $('').appendTo('body');
- $textarea = $('').appendTo('body');
- });
-
- afterEach(function() {
- $input.remove();
- $textarea.remove();
- setTimeout(() => {}, 2000);
- });
-
- it('a. Should clear input and textarea values during screenshot', function(done) {
- sinon.stub(window, 'html2canvas').resolves(document.createElement('canvas'));
- $button.click();
- expect($input.val()).to.equal('');
- expect($textarea.val()).to.equal('');
- html2canvas.restore();
- done();
- });
-
- it('b. Should restore input and textarea values after screenshot', function() {
- sinon.stub(window, 'html2canvas').resolves(document.createElement('canvas'));
- return waitForClick($button)
- .then(() => {
- expect($input.val()).to.equal('test');
- expect($textarea.val()).to.equal('test');
- html2canvas.restore();
- });
- });
- });
-
- describe('4. Modal and Floating Element Handling', function() {
- let $modal;
-
- beforeEach(function() {
- $modal = $('Modal Content
').appendTo('body');
- });
-
- afterEach(function() {
- $modal.remove();
- setTimeout(() => {}, 2000);
- });
-
-
- it('a. Should capture visible modals', function(done) {
- sinon.stub(window, 'html2canvas').callsFake(function(element) {
- expect($(element).find('.modal').length).to.equal(5);
- return Promise.resolve(document.createElement('canvas'));
- });
- $button.click();
- html2canvas.restore();
- done();
- });
- });
-
- describe('5. HTML2Canvas Integration', function() {
- let html2canvasStub, consoleErrorStub;
-
- afterEach(function() {
- if (html2canvasStub && html2canvasStub.restore) {
- html2canvasStub.restore();
- }
- if (consoleErrorStub && consoleErrorStub.restore) {
- consoleErrorStub.restore();
- }
- });
-
- it('a. Should call html2canvas with correct parameters', function() {
- html2canvasStub = sinon.stub(window, 'html2canvas').resolves(document.createElement('canvas'));
-
- return waitForClick($button)
- .then(() => {
- expect(html2canvasStub.calledWith(document.body)).to.be.true;
- });
- });
-
- it('b. Should handle html2canvas errors gracefully', function() {
- html2canvasStub = sinon.stub(window, 'html2canvas').rejects(new Error('Test error'));
- consoleErrorStub = sinon.stub(console, 'error');
-
- return waitForClick($button)
- .then(() => {
- expect(consoleErrorStub.called).to.be.true;
- expect(consoleErrorStub.firstCall.args[0]).to.be.an('error');
- expect(consoleErrorStub.firstCall.args[0].message).to.equal('Test error');
- });
- });
- });
-
- describe('6. Screenshot Generation', function() {
- afterEach(function() {
- setTimeout(() => {}, 2000);
- });
-
- /* Base64 string used instead of Blob
- it('a. Should create a blob from the canvas', function(done) {
- const canvas = document.createElement('canvas');
- sinon.stub(window, 'html2canvas').resolves(canvas);
- sinon.stub(canvas, 'toBlob').callsArgWith(0, new Blob());
- $button.click();
- html2canvas.restore();
- expect(canvas.toBlob.called).to.be.true;
- canvas.toBlob.restore();
- });
- */
-
- it('b. Should generate a Base64 PNG string when saving is confirmed', function(done) {
- const consoleStub = sinon.stub(console, 'log');
- $button.click();
- setTimeout(() => {
- expect(consoleStub.callCount).to.equal(2);
- const base64String = consoleStub.getCall(0).args[1];
- expect(base64String).to.be.a('string');
- expect(base64String).to.match(/^data:image\/png;base64,/);
- consoleStub.restore();
- done();
- }, 1000);
- });
- });
-
- describe('7. Download Functionality', function() {
- let createElementStub, appendChildStub, removeChildStub, html2canvasStub;
- let originalJQuery, jQueryStub, eachStub, originalCreateElement;
-
- beforeEach(function() {
- originalJQuery = window.$;
- originalCreateElement = document.createElement;
-
- jQueryStub = sinon.stub();
- eachStub = sinon.stub();
- jQueryStub.returns({
- each: eachStub,
- attr: sinon.stub(),
- val: sinon.stub(),
- addClass: sinon.stub(),
- removeClass: sinon.stub()
- });
- window.$ = jQueryStub;
-
- html2canvasStub = sinon.stub(window, 'html2canvas').resolves(document.createElement('canvas'));
-
- createElementStub = sinon.stub(document, 'createElement').callsFake(function(tagName) {
- if (tagName === 'a') {
- return {
- style: {},
- href: '',
- download: '',
- click: sinon.spy(),
- textContent: ''
- };
- }
- return originalCreateElement.call(document, tagName);
- });
- appendChildStub = sinon.stub(document.body, 'appendChild');
- removeChildStub = sinon.stub(document.body, 'removeChild');
-
- sinon.stub(URL, 'createObjectURL').returns('blob:http://example.com/test');
- sinon.stub(URL, 'revokeObjectURL');
- });
-
- afterEach(function() {
- sinon.restore();
- window.$ = originalJQuery;
- document.createElement = originalCreateElement;
- });
-
- it('a. Should create a temporary anchor element for download', function() {
- return waitForClick($button)
- .then(() => {
- expect(html2canvasStub.calledWith(document.body)).to.be.true;
- expect(createElementStub.calledWith('a')).to.be.true;
- expect(appendChildStub.calledOnce).to.be.true;
- expect(removeChildStub.calledOnce).to.be.true;
-
- const aElement = appendChildStub.getCall(0).args[0];
- expect(aElement.href).to.include('data:image/png;base64');
- expect(aElement.download).to.equal('screenshot.png');
- });
- });
-
- it('b. Should click the temporary anchor element programmatically', function() {
- return waitForClick($button)
- .then(() => {
- console.log("createElementStub: ", createElementStub, createElementStub.calledOnce);
- expect(createElementStub.calledOnce).to.be.true;
- });
- });
-
- it('c. Should remove the temporary anchor after download', function(done) {
- $button.click();
- setTimeout(() => {
- expect(removeChildStub.calledOnce).to.be.true;
- done();
- }, 1000);
- });
- });
-
- describe('8. Cross-browser Compatibility', function() {
- it('a. Should work in Chrome-like environments', function() {
- // Assuming we're running tests in a Chrome-like environment
- expect(() => $button.screenshotButton()).to.not.throw();
- });
-
- // Additional browser-specific tests would go here
- // These might need to be run in different environments or with browser mocks
- });
-
- describe('9. Performance', function() {
- it('a. Should capture and generate screenshot within acceptable time', function(done) {
- this.timeout(5000);
-
- const startTime = performance.now();
-
- $button.click();
-
- const endTime = performance.now();
- const duration = endTime - startTime;
- expect(duration).to.be.below(1000);
- done();
- });
- });
-
- describe('10. Error Handling', function() {
- var html2canvasStub, consoleErrorStub;
-
- beforeEach(function() {
- consoleErrorStub = sandbox.stub(console, 'error');
- setTimeout(() => {}, 2000);
- });
-
- afterEach(function() {
- if (html2canvasStub && html2canvasStub.restore) {
- html2canvasStub.restore();
- }
- if (consoleErrorStub && consoleErrorStub.restore) {
- consoleErrorStub.restore();
- }
- });
-
- it('a. Should log error when html2canvas is not loaded', function(done) {
- const originalHtml2Canvas = window.html2canvas;
- delete window.html2canvas;
-
- $button.click();
-
- expect(consoleErrorStub.calledOnce).to.be.true;
- expect(consoleErrorStub.args[0][0]).to.include('html2canvas is not loaded');
-
- window.html2canvas = originalHtml2Canvas;
- done();
- });
-
- it('b. Should handle errors during capture process', function() {
- let errorName = 'Capture failed';
- html2canvasStub = sinon.stub(window, 'html2canvas').rejects(new Error(errorName));
-
- return waitForClick($button)
- .then(() => {
- expect(consoleErrorStub.called).to.be.true;
- expect(consoleErrorStub.firstCall.args[0]).to.be.an('error');
- expect(consoleErrorStub.firstCall.args[0].message).to.equal(errorName);
- });
- });
- });
-
- describe('11. Configuration Options', function() {
- beforeEach(function() {
- });
-
- afterEach(function() {
- sinon.restore();
- setTimeout(() => {}, 2000);
- });
-
- it('a. Should apply custom button text correctly', function() {
- const customText = 'Custom Capture Screen';
- $button.screenshotButton({ buttonText: customText });
- expect($button.text()).to.equal(customText);
- });
-
- it('b. Should use custom filename for the downloaded image', function(done) {
- console.log("11.b");
- this.timeout(5000);
- const customFileName = 'custom-screenshot.png';
- $button.screenshotButton({ fileName: customFileName });
- const consoleStub = sinon.stub(console, 'log');
-
- $button.click();
- setTimeout(() => {
- console.log("consoleStub: ", consoleStub);
- try {
- expect(consoleStub.callCount).to.equal(2);
- const call = consoleStub.getCall(1);
- console.log("call: ", call);
- const a = call.args[1];
- console.log("a: ", a);
- // expect(consoleLogStub.calledWith("adding button a: ", customFileName)).to.be.true;
- } catch (e) {
- console.log("error: ", e);
- }
- consoleStub.restore();
- done();
- }, 1000);
- });
- });
-
- describe('12. Accessibility', function() {
- it('a. Should have appropriate ARIA attributes', function() {
- expect($button.attr('role')).to.equal('button');
- expect($button.attr('aria-label')).to.equal(defaultOptions.buttonText);
- });
-
- it('b. Should be keyboard accessible', function(done) {
- $button.on('keydown', function(e) {
- if (e.which === 13) { // Enter key
- done();
- }
- });
- const event = new KeyboardEvent('keydown', { 'keyCode': 13 });
- $button[0].dispatchEvent(event);
- });
- });
-
- describe('13. Security', function() {
- const inputValue = 'sensitive-info';
- const textareaValue = 'confidential-data';
- const idInput = 'testInput1';
- const idTextarea = 'testInput2';
-
- afterEach(function() {
- setTimeout(() => {}, 2000);
- });
-
- it('a. Should not capture sensitive information in inputs and textareas', function(done) {
- $('').appendTo('body');
- $('').appendTo('body');
- $button.click();
- const inputs = document.querySelectorAll('input, textarea');
- inputs.forEach(input => {
- expect(input.value).to.be.empty;
- });
- $('#' + idInput).remove();
- $('#' + idTextarea).remove();
- done();
- });
-
- it('b. Should restore input and textarea values after capture', function() {
-
- $('#' + idInput).remove();
- $('#' + idTextarea).remove();
- $('').appendTo('body');
- $('').appendTo('body');
-
- return waitForClick($button)
- .then(() => {
- setTimeout(() => {
- let $input = $('#' + idInput);
- let $textarea = $('#' + idTextarea);
- expect($input.val()).to.equal(inputValue);
- expect($textarea.val()).to.equal(textareaValue);
- $input.remove();
- $textarea.remove();
- }, 2000);
- });
- });
- });
-
- describe('14. CSS Interaction', function() {
- it('a. Should not break existing page styles', function() {
- const originalStyles = getComputedStyle(document.body);
- const newStyles = getComputedStyle(document.body);
- expect(originalStyles.cssText).to.equal(newStyles.cssText);
- });
-
- it('b. Should apply correct button styling', function() {
- const buttonStyles = getComputedStyle($button[0]);
- expect(buttonStyles.display).to.not.equal('none');
- // Add more specific style checks as per your plugin's CSS
- });
- });
-
- describe('15. jQuery Plugin Requirements', function() {
- it('a. Should return jQuery object for chaining', function() {
- const result = $button.screenshotButton();
- expect(result).to.equal($button);
- });
-
- it('b. Should initialize plugin on multiple elements', function() {
- $('body').append('');
- $('.test-class').screenshotButton();
- expect($('.test-class').length).to.equal(2);
- $('.test-class').remove();
- });
- });
-
- describe('16. Memory Management', function() {
- it('a. Should not leak memory on repeated initialization and destruction', function() {
- const initialMemory = performance.memory ? performance.memory.usedJSHeapSize : 0;
- for (let i = 0; i < 500; i++) {
- $button.screenshotButton();
- $button.empty();
- }
- const finalMemory = performance.memory ? performance.memory.usedJSHeapSize : 0;
- expect(finalMemory - initialMemory).to.be.below(1000000); // 1 MB ish
- });
-
- it('b. Should remove all created DOM elements after use', function() {
- $button.screenshotButton();
- const initialChildCount = $button[0].childElementCount;
-
- return waitForClick($button)
- .then(() => {
- expect($button[0].childElementCount).to.equal(initialChildCount);
- });
- });
- });
-
- describe('17. Responsiveness', function() {
- var html2canvasStub;
-
- beforeEach(function() {
- setTimeout(() => {}, 2000);
- });
-
- afterEach(function() {
- if (html2canvasStub && html2canvasStub.restore) {
- html2canvasStub.restore();
- }
- $button.width(100).height(50);
- });
-
- it('a. Should behave correctly on different screen sizes', function() {
- const viewports = [
- {width: 320, height: 568}, // iPhone 5
- {width: 1024, height: 768}, // iPad
- {width: 1920, height: 1080} // Full HD
- ];
-
- viewports.forEach(size => {
- $button.width(size.width).height(size.height);
- $button.screenshotButton();
- expect($button.hasClass(flagIsHidden)).to.be.false;
- expect($button.width()).to.be.at.most(size.width);
- });
- });
-
- it('', function() {});
- });
-});
\ No newline at end of file
diff --git a/submission - backup/test_plugin_display_png_Mocha.js b/submission - backup/test_plugin_display_png_Mocha.js
deleted file mode 100644
index 38f0fb6..0000000
--- a/submission - backup/test_plugin_display_png_Mocha.js
+++ /dev/null
@@ -1,376 +0,0 @@
-
-describe('Image Annotation Control', function() {
- var $annotatorPNG, $toolbox, $inputUploadImage, $buttonAddArrow, $buttonAddTextbox, $selectAddSymbol, $inputColourPicker, $buttonEraseMode, $buttonSaveImage, $containerAnnotation, $canvasAnnotation;
-
- beforeEach(function() {
- $annotatorPNG = $(document).find("." + flagAnnotatorPNG);
- $annotatorPNG.annotatorPNG(annotatorSettings);
- $toolbox = $annotatorPNG.find("." + flagToolbox);
- $inputUploadImage = $toolbox.find("." + flagUploadImage);
- $buttonAddArrow = $toolbox.find("." + flagAddArrow);
- $buttonAddTextbox = $toolbox.find("." + flagAddTextbox);
- $selectAddSymbol = $toolbox.find("." + flagAddSymbol);
- $inputColourPicker = $toolbox.find("." + flagColourPicker);
- $buttonEraseMode = $toolbox.find("." + flagEraseMode);
- $buttonSaveImage = $toolbox.find("." + flagSaveImage);
- $containerAnnotation = $annotatorPNG.find("." + flagContainerAnnotation);
- $canvasAnnotation = $containerAnnotation.find("." + flagCanvasAnnotation);
- });
-
- afterEach(function() {
- let canvas = $($containerAnnotation.children()[0].children[0]).clone();
- $containerAnnotation.empty();
- $containerAnnotation.append(canvas);
- });
-
- describe('1. Initialization and Setup', function() {
- it('a. Should initialize correctly on a given DOM element', async function() {
- expect($annotatorPNG).to.exist;
- });
-
- it('b. Should create canvas with correct dimensions', async function() {
- let canvas = $canvasAnnotation.data(keyFabric);
- expect(canvas.width).to.equal(800);
- expect(canvas.height).to.equal(600);
- expect($canvasAnnotation.attr('width')).to.equal('800');
- expect($canvasAnnotation.attr('height')).to.equal('600');
- });
-
- it('c. Should have all UI elements present with correct values after initialization', async function() {
- expect($annotatorPNG.find("." + flagToolbox)).to.have.length(1);
- expect($annotatorPNG.find("." + flagUploadImage)).to.have.length(1);
- expect($annotatorPNG.find("." + flagAddArrow)).to.have.length(1);
- expect($annotatorPNG.find("." + flagAddTextbox)).to.have.length(1);
- expect($annotatorPNG.find("." + flagAddSymbol)).to.have.length(1);
- expect($annotatorPNG.find("." + flagColourPicker)).to.have.length(1);
- expect($annotatorPNG.find("." + flagEraseMode)).to.have.length(1);
- expect($annotatorPNG.find("." + flagSaveImage)).to.have.length(1);
- expect($annotatorPNG.find("." + flagContainerAnnotation)).to.have.length(1);
- expect($annotatorPNG.find("." + flagCanvasAnnotation).length > 0).to.be.true;
- /*
- expect($toolbox).to.exist;
- expect($inputUploadImage).to.exist;
- expect($buttonAddArrow).to.exist;
- expect($buttonAddTextbox).to.exist;
- expect($selectAddSymbol).to.exist;
- expect($selectAddSymbol.find("option")).to.exist;
- expect($inputColourPicker).to.exist;
- expect($buttonEraseMode).to.exist;
- expect($buttonSaveImage).to.exist;
- expect($containerAnnotation).to.exist;
- expect($canvasAnnotation).to.exist;
- */
-
- expect($inputUploadImage.val()).to.equal('');
- expect($inputColourPicker.val()).to.equal('#ff0000');
- expect($buttonSaveImage.text().length > 0).to.be.true; // For unkown settings argument value
- expect($buttonSaveImage.text()).to.equal('Save Image');
- expect($canvasAnnotation.data(keyFabric)).to.exist;
- });
- });
-
- describe('2. Image Upload and Display', function() {
- it('a. Should successfully upload a PNG file', function(done) {
- const file = new File([''], 'screenshot (16).png', { type: 'image/png' });
- const fileInput = $inputUploadImage[0];
-
- const dataTransfer = new DataTransfer();
- dataTransfer.items.add(file);
- fileInput.files = dataTransfer.files;
-
- $(fileInput).trigger('change');
-
- setTimeout(() => {
- let canvas = $canvasAnnotation.data(keyFabric);
- if (canvas) console.log("canvas.backgroundImage: " + canvas.backgroundImage);
- expect(canvas.backgroundImage).to.exist;
- done();
- }, 100);
- });
-
- it('b. Should display the uploaded image correctly on the canvas', function(done) {
- const file = new File([''], 'screenshot (16).png', { type: 'image/png' });
- const fileInput = $inputUploadImage[0];
-
- const dataTransfer = new DataTransfer();
- dataTransfer.items.add(file);
- fileInput.files = dataTransfer.files;
-
- $(fileInput).trigger('change');
-
- setTimeout(() => {
- try {
- let canvas = $canvasAnnotation.data(keyFabric);
- let context = canvas.getContext('2d');
- let imageData = context.getImageData(0, 0, canvas.width, canvas.height);
- expect(canvas.width).to.equal(800);
- expect(canvas.height).to.equal(600);
- expect(imageData.data.length).to.equal(800 * 600 * 4);
- done();
- }
- catch (e) {
- console.log("Error during canvas initialisation: " + e);
- done(e);
- }
- }, 100);
- });
-
- it('d. Should handle invalid file types', async function() {
- const file = new File([''], 'test.jpg', { type: 'image/jpeg' });
- const fileInput = $inputUploadImage[0];
-
- const confirmStub = sinon.stub(window, 'alert').returns(true);
- const dataTransfer = new DataTransfer();
- dataTransfer.items.add(file);
- fileInput.files = dataTransfer.files;
-
- expect(() => $(fileInput).trigger('change')).to.throw();
- confirmStub.restore();
- });
- });
-
- describe('3. Arrow Addition', function() {
- it('a. Should create a new arrow on the canvas when "Add Arrow" is clicked', async function() {
- let canvas = $canvasAnnotation.data(keyFabric);
- console.log("canvas: " + canvas);
- await waitForClick($buttonAddArrow);
- console.log("canvas after: " + canvas);
- expect(canvas.getObjects()).to.have.lengthOf(1);
- expect(canvas.getObjects()[0].type).to.equal('path');
- });
-
- it('b. Should create arrow with correct default properties', async function() {
- let canvas = $canvasAnnotation.data(keyFabric);
- await waitForClick($buttonAddArrow);
- const arrow = canvas.getObjects()[0];
- expect(arrow.fill).to.equal('#ff0000');
- expect(arrow.stroke).to.equal('#ff0000');
- expect(arrow.strokeWidth).to.equal(2);
- });
-
- it('c. Should allow multiple arrows to be added to the canvas', async function() {
- let canvas = $canvasAnnotation.data(keyFabric);
- await waitForClick($buttonAddArrow);
- await waitForClick($buttonAddArrow);
- expect(canvas.getObjects()).to.have.lengthOf(2);
- });
- });
-
- describe('4. Textbox Addition', function() {
- it('a. Should create a new textbox on the canvas when "Add Textbox" is clicked', async function() {
- let canvas = $canvasAnnotation.data(keyFabric);
- await waitForClick($buttonAddTextbox);
- expect(canvas.getObjects()).to.have.lengthOf(1);
- expect(canvas.getObjects()[0].type).to.equal('textbox');
- });
-
- it('b. Should create textbox with correct default properties', async function() {
- let canvas = $canvasAnnotation.data(keyFabric);
- await waitForClick($buttonAddTextbox);
- const textbox = canvas.getObjects()[0];
- expect(textbox.fontSize).to.equal(20);
- expect(textbox.left).to.equal(100);
- expect(textbox.top).to.equal(100);
- });
-
- it('c. Should allow text to be entered and edited in the textbox', async function() {
- this.timeout(10000);
- let canvas = $canvasAnnotation.data(keyFabric);
- await waitForClick($buttonAddTextbox);
- const textbox = canvas.getObjects()[0];
- console.log("textbox: " + textbox);
- textbox.text = 'New Text';
- console.log("textbox: " + textbox);
- canvas.renderAll();
- await new Promise(resolve => setTimeout(resolve, 50));
- expect(textbox.text).to.equal('New Text');
- });
-
- it('d. Should allow multiple textboxes to be added to the canvas', async function() {
- let canvas = $canvasAnnotation.data(keyFabric);
- await waitForClick($buttonAddTextbox);
- await waitForClick($buttonAddTextbox);
- expect(canvas.getObjects()).to.have.lengthOf(2);
- });
- });
-
- describe('5. Element Manipulation', function() {
- it('a. Should allow arrows to be selected, moved, resized, and rotated', async function() {
- let canvas = $canvasAnnotation.data(keyFabric);
- await waitForClick($buttonAddArrow);
- const arrow = canvas.getObjects()[0];
- arrow.set({ left: 150, top: 150, scaleX: 2, angle: 45 });
- canvas.renderAll();
- expect(arrow.left).to.equal(150);
- expect(arrow.top).to.equal(150);
- expect(arrow.scaleX).to.equal(2);
- expect(arrow.angle).to.equal(45);
- });
-
- it('b. Should allow textboxes to be selected, moved, resized, and rotated', async function() {
- let canvas = $canvasAnnotation.data(keyFabric);
- await waitForClick($buttonAddTextbox);
- const textbox = canvas.getObjects()[0];
- textbox.set({ left: 150, top: 150, scaleX: 2, angle: 45 });
- canvas.renderAll();
- expect(textbox.left).to.equal(150);
- expect(textbox.top).to.equal(150);
- expect(textbox.scaleX).to.equal(2);
- expect(textbox.angle).to.equal(45);
- });
- });
-
- describe('6. Erasing Elements', function() {
- afterEach(function() {
- setTimeout(() => {}, 2000);
- $annotatorPNG.annotatorPNG(annotatorSettings);
- });
-
- it('a. Should remove the currently selected arrow when "Erase Element" is clicked', async function() {
- let canvas = $canvasAnnotation.data(keyFabric);
- await waitForClick($buttonAddArrow);
- canvas.setActiveObject(canvas.getObjects()[0]);
- await waitForClick($buttonEraseMode);
- expect(canvas.getObjects()).to.have.lengthOf(0);
- });
-
- it('b. Should remove the currently selected textbox when "Erase Element" is clicked', function(done) {
- this.timeout(10000);
- let canvas = $canvasAnnotation.data(keyFabric);
- waitForClick($buttonAddTextbox).then(() => {
- canvas.setActiveObject(canvas.getObjects()[0]);
- canvas.renderAll();
- waitForClick($buttonEraseMode).then(() => {
- canvas.renderAll();
- expect(canvas.getObjects()).to.have.lengthOf(0);
- done();
- });
- });
- });
-
- it('c. Should not affect other elements on the canvas when erasing', function(done) {
- this.timeout(10000);
- let canvas = $canvasAnnotation.data(keyFabric);
- waitForClick($buttonAddArrow).then(() => {
- console.log("canvas.getObjects()[0]: ", canvas.getObjects()[0]);
- waitForClick($buttonAddTextbox).then(() => {
- canvas.setActiveObject(canvas.getObjects()[0]);
- waitForClick($buttonEraseMode).then(() => {
- expect(canvas.getObjects()).to.have.lengthOf(1);
- console.log("canvas.getObjects()[0]: ", canvas.getObjects()[0]);
- expect(canvas.getObjects()[0].text).to.exist;
- done();
- });
- });
- });
- });
- });
-
- describe('7. Saving Functionality', function() {
- it('a. Should trigger confirmation dialog when "Save" is clicked', async function() {
- const confirmStub = sinon.stub(window, 'confirm').returns(true);
- const alertStub = sinon.stub(window, 'alert').returns(true);
- await waitForClick($buttonSaveImage);
- expect(confirmStub.calledOnce).to.be.true;
- confirmStub.restore();
- alertStub.restore();
- });
-
- it('b. Should prevent saving when confirmation dialog is canceled', async function() {
- const confirmStub = sinon.stub(window, 'confirm').returns(false);
- const consoleStub = sinon.stub(console, 'log');
- await waitForClick($buttonSaveImage);
- expect(consoleStub.called).to.be.false;
- confirmStub.restore();
- consoleStub.restore();
- });
-
- it('c. Should generate a Base64 PNG string when saving is confirmed', async function() {
- sinon.stub(window, 'confirm').returns(true);
- const alertStub = sinon.stub(window, 'alert').returns(true);
- const consoleStub = sinon.stub(console, 'log');
- await waitForClick($buttonSaveImage);
- expect(consoleStub.calledOnce).to.be.true;
- const base64String = consoleStub.getCall(0).args[1];
- expect(base64String).to.be.a('string');
- expect(base64String).to.match(/^data:image\/png;base64,/);
- window.confirm.restore();
- consoleStub.restore();
- alertStub.restore();
- });
- });
-
- describe('8. Edge Cases and Error Handling', function() {
- it('a. Should handle initialization on invalid DOM element', async function() {
- expect(() => $('#non-existent-element').imageAnnotator()).to.throw();
- });
- });
-
- describe('9. Performance', function() {
- it('a. Should capture and generate screenshot within acceptable time', function(done) {
- this.timeout(5000);
-
- const startTime = performance.now();
- const alertStub = sinon.stub(window, 'alert').returns(true);
- const confirmStub = sinon.stub(window, 'confirm').returns(true);
-
- $buttonSaveImage.click();
-
- const endTime = performance.now();
- const duration = endTime - startTime;
- expect(duration).to.be.below(1000);
- alertStub.restore();
- confirmStub.restore();
- done();
- });
- });
-
- describe('10. Accessibility', function() {
- it('a. Should have appropriate ARIA labels for all interactive elements', async function() {
- expect($inputUploadImage.attr('aria-label').length > 0).to.be.true;
- expect($buttonAddArrow.attr('aria-label').length > 0).to.be.true;
- expect($buttonAddTextbox.attr('aria-label').length > 0).to.be.true;
- expect($selectAddSymbol.attr('aria-label').length > 0).to.be.true;
- expect($inputColourPicker.attr('aria-label').length > 0).to.be.true;
- expect($buttonEraseMode.attr('aria-label').length > 0).to.be.true;
- expect($buttonSaveImage.attr('aria-label').length > 0).to.be.true;
- expect($canvasAnnotation.attr('aria-label').length > 0).to.be.true;
- });
- });
-
- describe('11. jQuery Plugin Requirements', function() {
- it('a. Should return jQuery object for chaining', function() {
- const result = $annotatorPNG.annotatorPNG(annotatorSettings);
- expect(result).to.equal($annotatorPNG);
- });
-
- it('b. Should initialize plugin on multiple elements', function() {
- $('body').append('');
- $('.test-class').annotatorPNG(annotatorSettings);
- expect($('.test-class').length).to.equal(2);
- $('.test-class').remove();
- });
- });
-
- describe('12. Memory Management', function() {
- it('a. Should not leak memory on repeated initialization and destruction', function() {
- const initialMemory = performance.memory ? performance.memory.usedJSHeapSize : 0;
- for (let i = 0; i < 500; i++) {
- $annotatorPNG.annotatorPNG(annotatorSettings);
- $canvasAnnotation.data(keyFabric).dispose();
- }
- const finalMemory = performance.memory ? performance.memory.usedJSHeapSize : 0;
- expect(finalMemory - initialMemory).to.be.below(1000000); // 1 MB ish
- });
-
- it('b. Should remove all created DOM elements after use', function() {
- const initialChildCount = $annotatorPNG[0].childElementCount;
- const initialCanvasCount = $containerAnnotation[0].childElementCount;
-
- $annotatorPNG.annotatorPNG(annotatorSettings);
-
- expect($annotatorPNG[0].childElementCount).to.equal(initialChildCount);
- expect($containerAnnotation[0].childElementCount).to.equal(initialCanvasCount);
- });
- });
-});
\ No newline at end of file
diff --git a/submission - backup/view_capture_screen.html b/submission - backup/view_capture_screen.html
deleted file mode 100644
index 2b71544..0000000
--- a/submission - backup/view_capture_screen.html
+++ /dev/null
@@ -1,113 +0,0 @@
-
-
-
-
-
- Simple Layout Template
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Test Modal
-
This is a test modal.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/submission - backup/view_display_png.html b/submission - backup/view_display_png.html
deleted file mode 100644
index 8fde85b..0000000
--- a/submission - backup/view_display_png.html
+++ /dev/null
@@ -1,84 +0,0 @@
-
-
-
-
-
- Image Annotation Control
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file